From 3a1d922d817fe570a34ce94bf5ec3214369d5af8 Mon Sep 17 00:00:00 2001 From: Jakob Odersky Date: Thu, 29 Mar 2018 13:11:43 -0700 Subject: Allow deserialization of optional fields if they are omitted Fixes #5 --- build.sbt | 2 +- src/main/scala/DerivedFormats.scala | 7 ++++++- src/test/scala/ProductTypeFormatTests.scala | 17 +++++++++++++++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 23c577f..5d595be 100644 --- a/build.sbt +++ b/build.sbt @@ -17,7 +17,7 @@ scalacOptions ++= Seq( libraryDependencies ++= Seq( "io.spray" %% "spray-json" % "1.3.4", - "com.propensive" %% "magnolia" % "0.7.1", + "com.propensive" %% "magnolia" % "0.7.2-SNAPSHOT", "org.scalatest" %% "scalatest" % "3.0.2" % "test" ) diff --git a/src/main/scala/DerivedFormats.scala b/src/main/scala/DerivedFormats.scala index d0cac38..5bba08a 100644 --- a/src/main/scala/DerivedFormats.scala +++ b/src/main/scala/DerivedFormats.scala @@ -24,7 +24,12 @@ trait DerivedFormats { self: BasicFormats => ctx.rawConstruct(Seq.empty) } else { ctx.construct { param => - param.typeclass.read(obj.fields(param.label)) + val fieldValue = if (param.isOption) { + obj.fields.getOrElse(param.label, JsNull) + } else { + obj.fields(param.label) + } + param.typeclass.read(fieldValue) } } case js => diff --git a/src/test/scala/ProductTypeFormatTests.scala b/src/test/scala/ProductTypeFormatTests.scala index ce05000..d602ff4 100644 --- a/src/test/scala/ProductTypeFormatTests.scala +++ b/src/test/scala/ProductTypeFormatTests.scala @@ -74,4 +74,21 @@ class ProductTypeFormatTests """{"h": {"x":true}}""" ) + case class Opt(x: Option[Int]) + implicit val ofmt = jsonFormat[Opt] + + "Optional fields with some value" should behave like checkRoundtrip( + Opt(Some(2)), + """{"x":2}""" + ) + + "Optional fields with no value (null)" should behave like checkRoundtrip( + Opt(None), + """{"x":null}""" + ) + + "Optional fields with no value (undefined)" should "deserialize" in { + assert("{}".parseJson.convertTo[Opt] == Opt(None)) + } + } -- cgit v1.2.3