Skip to content
This repository was archived by the owner on Aug 14, 2023. It is now read-only.

Commit 083f4b9

Browse files
Merge pull request kifi#4 from vital-software/fix/remove-robust-json-parsing
Remove robust json parsing
2 parents 78c254f + 7519854 commit 083f4b9

File tree

4 files changed

+14
-86
lines changed

4 files changed

+14
-86
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
## [Unreleased]
44

5+
- Removed robust Json parsing implementation. Moving
6+
this to the client package to have more control.
7+
58
## [0.5.0] - 2018-08-09
69

710
### Breaking changes

src/main/scala/com/github/vitalsoftware/macros/JsonFormatAnnotation.scala

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -48,53 +48,31 @@ class jsonMacro(useDefaults: Boolean) {
4848
}
4949
}
5050

51-
/**
52-
* Generates implicit json.Formats that fallback to the defaults is the initial parsing fails.
53-
*/
5451
def jsonFormatter(className: TypeName, fields: List[ValDef]) = {
5552
fields.length match {
5653
case 0 => c.abort(c.enclosingPosition, "Cannot create json formatter for case class with no fields")
5754
case _ =>
58-
val lowPriorityFormats = if (useDefaults) {
59-
q"private val lowPriorityFormats = play.api.libs.json.Json.using[play.api.libs.json.Json.WithDefaultValues].format[$className]"
55+
if (useDefaults) {
56+
q"implicit val jsonAnnotationFormat = play.api.libs.json.Json.using[play.api.libs.json.Json.WithDefaultValues].format[$className]"
6057
} else {
61-
q"private val lowPriorityFormats = play.api.libs.json.Json.format[$className]"
58+
q"implicit val jsonAnnotationFormat = play.api.libs.json.Json.format[$className]"
6259
}
63-
64-
Seq(
65-
lowPriorityFormats,
66-
q"""
67-
private val robustReads = new play.api.libs.json.Reads[$className] {
68-
override def reads(json: play.api.libs.json.JsValue) = lowPriorityFormats.reads(json) match {
69-
case s: play.api.libs.json.JsSuccess[_] => s
70-
case e: play.api.libs.json.JsError =>
71-
val transforms = e.errors.map(_._1)
72-
.filter(_.path.size == 1)
73-
.map(_.json.prune)
74-
.reduce(_ andThen _)
75-
76-
json.transform(transforms).flatMap(lowPriorityFormats.reads _).orElse(e)
77-
}
78-
}
79-
""",
80-
q"implicit val jsonAnnotationFormat = play.api.libs.json.Format(robustReads, lowPriorityFormats)"
81-
)
8260
}
8361
}
8462

85-
def modifiedCompanion(compDeclOpt: Option[ModuleDef], format: Seq[Tree], className: TypeName) = {
63+
def modifiedCompanion(compDeclOpt: Option[ModuleDef], format: ValDef, className: TypeName) = {
8664
compDeclOpt map { compDecl =>
8765
// Add the formatter to the existing companion object
8866
val q"object $obj extends ..$bases { ..$body }" = compDecl
8967
q"""
9068
object $obj extends ..$bases {
9169
..$body
92-
..$format
70+
$format
9371
}
9472
"""
9573
} getOrElse {
9674
// Create a companion object with the formatter
97-
q"object ${className.toTermName} { ..$format }"
75+
q"object ${className.toTermName} { $format }"
9876
}
9977
}
10078

src/test/scala/com/github/vitalsoftware/macros/JsonFormatAnnotationTest.scala

Lines changed: 4 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,20 @@ package com.github.vitalsoftware.macros
33
import org.specs2.mutable.Specification
44
import play.api.libs.json._
55

6-
@json case class Person(name: String, age: Int, gender: Option[String])
7-
@jsonDefaults case class Person2(name: String, age: Int = 7, gender: Option[String] = None)
8-
@jsonDefaults case class Test(f1: Int = 1, f2: String = "2", f3: Boolean = true, f4: Option[Test])
6+
@json case class Person(name: String, age: Int)
7+
@jsonDefaults case class Person2(name: String, age: Int = 7)
98

109
class JsonFormatAnnotationTest extends Specification {
1110

1211
"@json annotation" should {
1312

1413
"create correct formatter for case class with >= 2 fields" in {
1514

16-
val person = Person("Victor Hugo", 46, Some("Male"))
15+
val person = Person("Victor Hugo", 46)
1716
val json = Json.toJson(person)
1817
json === Json.obj(
1918
"name" -> "Victor Hugo",
20-
"age" -> 46,
21-
"gender" -> "Male"
19+
"age" -> 46
2220
)
2321
Json.fromJson[Person](json).asOpt must beSome(person)
2422
}
@@ -37,55 +35,4 @@ class JsonFormatAnnotationTest extends Specification {
3735
Json.fromJson[Person2](Json.obj("name" -> "Victor Hugo")).asOpt must beSome(person)
3836
}
3937
}
40-
41-
"robustParsing" should {
42-
"make invalid option values None" in {
43-
val json = Json.obj(
44-
"name" -> "Victor Hugo",
45-
"age" -> 46,
46-
"gender" -> true
47-
)
48-
49-
Json.fromJson[Person](json).asOpt must beSome(Person("Victor Hugo", 46, None))
50-
Json.fromJson[Person2](json).asOpt must beSome(Person2("Victor Hugo", 46))
51-
}
52-
53-
"make invalid values with defaults fallback to the default" in {
54-
val json = Json.obj(
55-
"name" -> "Victor Hugo",
56-
"age" -> "non age"
57-
)
58-
59-
Json.fromJson[Person2](json).asOpt must beSome(Person2("Victor Hugo", 7))
60-
}
61-
62-
"throw on invalid values which are not optional or default" in {
63-
val json = Json.obj(
64-
"name" -> "Victor Hugo",
65-
"age" -> "non age"
66-
)
67-
68-
val result = Json.fromJson[Person](json)
69-
70-
result match {
71-
case e: JsError =>
72-
e.errors.head._1.path.head.asInstanceOf[KeyPathNode].key mustEqual("age")
73-
e.errors.head._2.head.message must contain("error.expected.jsnumber")
74-
case _ =>
75-
result must beAnInstanceOf[JsError]
76-
}
77-
}
78-
79-
"multiple defaults must get replaced" in {
80-
val json = Json.obj("f1" -> "str", "f2" -> false, "f3" -> 3, "f4" -> "not test")
81-
val result = Json.fromJson[Test](json)
82-
result match {
83-
case JsSuccess(value, paths) =>
84-
value mustEqual(Test(f4 = None))
85-
paths.path.map(_.toString) must contain(allOf("/f1", "/f2", "/f3", "/f4"))
86-
.setMessage("success result should contain paths of failed keys")
87-
case _ => result must beAnInstanceOf[JsSuccess[Test]]
88-
}
89-
}
90-
}
9138
}

version.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
version in ThisBuild := "0.5.1-SNAPSHOT"
1+
version in ThisBuild := "0.6.0-SNAPSHOT"

0 commit comments

Comments
 (0)