aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG.md4
-rw-r--r--build.sbt2
-rw-r--r--shared/src/main/scala/DerivedFormats.scala22
-rw-r--r--shared/src/test/scala/FieldNameTests.scala1
-rw-r--r--shared/src/test/scala/OptionFieldTests.scala24
-rw-r--r--shared/src/test/scala/ProductTypeFormatTests.scala20
6 files changed, 49 insertions, 24 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 4c52155..54ffb7e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,7 @@
+# UNRELEASED
+
+- Upgrade magnolia to official upstream, 0.10.0.
+
# Version 0.6.0
- Value classes are handled transparently. I.e. their values are
diff --git a/build.sbt b/build.sbt
index f4a72e0..349f96e 100644
--- a/build.sbt
+++ b/build.sbt
@@ -21,7 +21,7 @@ lazy val sprayJsonDerivation =
),
libraryDependencies ++= Seq(
"io.crashbox" %%% "spray-json" % "1.3.4-1",
- "io.crashbox" %%% "magnolia" % "0.8.0-1"
+ "com.propensive" %%% "magnolia" % "0.10.0"
)
)
.platformsSettings(JVMPlatform, JSPlatform)(
diff --git a/shared/src/main/scala/DerivedFormats.scala b/shared/src/main/scala/DerivedFormats.scala
index 7c13314..c4781fa 100644
--- a/shared/src/main/scala/DerivedFormats.scala
+++ b/shared/src/main/scala/DerivedFormats.scala
@@ -29,14 +29,16 @@ trait DerivedFormats { self: BasicFormats =>
val param = ctx.parameters.head
param.typeclass.write(param.dereference(value))
} else {
- val fields: Seq[(String, JsValue)] = ctx.parameters.collect {
- case param
- if !param.option || param.dereference(value) != None || printNull =>
- extractFieldName(param.label) -> param.typeclass.write(
- param.dereference(value)
- )
+ val fields: Seq[(String, JsValue)] = ctx.parameters.map { param =>
+ extractFieldName(param.label) -> param.typeclass.write(
+ param.dereference(value)
+ )
+ }
+ val nullFiltered = fields.filter {
+ case (_, JsNull) => printNull
+ case (_, _) => true
}
- JsObject(fields: _*)
+ JsObject(nullFiltered: _*)
}
override def read(value: JsValue): T = value match {
@@ -48,11 +50,7 @@ trait DerivedFormats { self: BasicFormats =>
} else {
ctx.construct { param =>
val fieldName = extractFieldName(param.label)
- val fieldValue = if (param.option) {
- obj.fields.getOrElse(fieldName, JsNull)
- } else {
- obj.fields(fieldName)
- }
+ val fieldValue = obj.fields.getOrElse(fieldName, JsNull)
param.typeclass.read(fieldValue)
}
}
diff --git a/shared/src/test/scala/FieldNameTests.scala b/shared/src/test/scala/FieldNameTests.scala
index ef4064d..cda5837 100644
--- a/shared/src/test/scala/FieldNameTests.scala
+++ b/shared/src/test/scala/FieldNameTests.scala
@@ -9,6 +9,7 @@ class FieldNameTests extends FlatSpec with FormatTests {
case class C(abA: String)
trait All extends DefaultJsonProtocol with DerivedFormats {
+ implicit val aFormat = jsonFormat[A]
implicit val bFormat = jsonFormat[B]
implicit val cFormat = jsonFormat[C]
}
diff --git a/shared/src/test/scala/OptionFieldTests.scala b/shared/src/test/scala/OptionFieldTests.scala
index 8cabf25..ac925d7 100644
--- a/shared/src/test/scala/OptionFieldTests.scala
+++ b/shared/src/test/scala/OptionFieldTests.scala
@@ -6,7 +6,8 @@ class OptionFieldTests
extends FlatSpec
with FormatTests {
- case class Opt(x: Option[Int])
+ sealed trait Super
+ case class Opt(x: Option[Int]) extends Super
object HideNull extends DerivedJsonProtocol {
override def printNull = false
@@ -49,5 +50,26 @@ class OptionFieldTests
assert("{}".parseJson.convertTo[Opt] == Opt(None))
}
+ {
+ import ShowNull._
+ implicit val superFmt = jsonFormat[Super]
+ "Option fields of ADTs" should behave like checkRoundtrip(
+ Opt(Some(2)): Super,
+ """{ "@type": "Opt", "x":2}"""
+ )
+ }
+
+ sealed trait Enum
+ case class Value(x: Int) extends Enum
+ case class Wrapper(enum: Option[Enum])
+
+ import ShowNull._
+ implicit val enumFormat: RootJsonFormat[Enum] = jsonFormat[Enum]
+ implicit val superFmt: RootJsonFormat[Wrapper] = jsonFormat[Wrapper]
+ "Option fields of inner ADTs" should behave like checkRoundtrip(
+ Wrapper(Some(Value(1))),
+ """{"enum":{"@type":"Value", "x": 1}}"""
+ )
+
}
diff --git a/shared/src/test/scala/ProductTypeFormatTests.scala b/shared/src/test/scala/ProductTypeFormatTests.scala
index d7721ba..7964743 100644
--- a/shared/src/test/scala/ProductTypeFormatTests.scala
+++ b/shared/src/test/scala/ProductTypeFormatTests.scala
@@ -12,8 +12,8 @@ class ProductTypeFormatTests
case class C(b: B)
case object D
case class E(d: D.type)
- case class F(x: Int)
- case class G(f: F)
+ case class FF(x: Int)
+ case class G(f: FF)
implicit val aFormat: RootJsonFormat[A] = jsonFormat[A]
implicit val bFormat: RootJsonFormat[B] = jsonFormat[B]
@@ -44,28 +44,28 @@ class ProductTypeFormatTests
)
// custom format for F, that inverts the value of parameter x
- implicit val fFormat: RootJsonFormat[F] = new RootJsonFormat[F] {
- override def write(f: F): JsValue = JsObject("y" -> f.x.toJson)
- override def read(js: JsValue): F =
- F(js.asJsObject.fields("y").convertTo[Int])
+ implicit val fFormat: RootJsonFormat[FF] = new RootJsonFormat[FF] {
+ override def write(f: FF): JsValue = JsObject("y" -> f.x.toJson)
+ override def read(js: JsValue): FF =
+ FF(js.asJsObject.fields("y").convertTo[Int])
}
"Overriding with a custom format" should behave like checkRoundtrip(
- F(2),
+ FF(2),
"""{"y":2}"""
)
implicit val gFormat: RootJsonFormat[G] = jsonFormat[G]
"Derving a format with a custom child format" should behave like checkRoundtrip(
- G(F(2)),
+ G(FF(2)),
"""{"f": {"y":2}}"""
)
case class H(x: Boolean)
case class I(h: H)
- // there is no format defined for H, Magnolia will generate one automatically
+ implicit val hFormat = jsonFormat[H]
implicit val iFormat: RootJsonFormat[I] = jsonFormat[I]
"Deriving a format that has no implicit child formats available" should behave like checkRoundtrip(
@@ -105,7 +105,7 @@ class ProductTypeFormatTests
implicit def vcg[T: JsonFormat] = jsonFormat[ProductTypeFormatTests.WrapperGeneric[T]]
"Value classes with generic parameters" should behave like checkRoundtrip(
- ProductTypeFormatTests.WrapperGeneric[F](F(42)),
+ ProductTypeFormatTests.WrapperGeneric[FF](FF(42)),
"""{"y": 42}"""
)