From ad0275da872cc903992e3c82a0e3fe770028480c Mon Sep 17 00:00:00 2001 From: Simon Schenk Date: Mon, 22 Apr 2024 13:49:44 +0200 Subject: [PATCH] fix: decode ADT with 3 cases with noDiscriminator (#678) * fix: decode ADT with 3 cases with noDiscriminator * generate readme --- README.md | 18 ++++++------- .../scala/zio/schema/codec/JsonCodec.scala | 3 ++- .../zio/schema/codec/JsonCodecSpec.scala | 26 +++++++++++++++++++ 3 files changed, 37 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 5c7882a66..0697e464c 100644 --- a/README.md +++ b/README.md @@ -39,17 +39,17 @@ _ZIO Schema_ is used by a growing number of ZIO libraries, including [ZIO Flow]( In order to use this library, we need to add the following lines in our `build.sbt` file: ```scala -libraryDependencies += "dev.zio" %% "zio-schema" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.0.1" -libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.0.1" +libraryDependencies += "dev.zio" %% "zio-schema" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-avro" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-bson" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-json" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-msg-pack" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-protobuf" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-thrift" % "1.1.0" +libraryDependencies += "dev.zio" %% "zio-schema-zio-test" % "1.1.0" // Required for the automatic generic derivation of schemas -libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.0.1" +libraryDependencies += "dev.zio" %% "zio-schema-derivation" % "1.1.0" libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided" ``` diff --git a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala index 582eff73e..758b5adbd 100644 --- a/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala +++ b/zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala @@ -711,7 +711,7 @@ object JsonCodec { (trace: List[JsonError], in: RetractReader) => { if (noDiscriminators) { - val rr = RecordingReader(in) + var rr = RecordingReader(in) val it = cases.iterator var result: Option[Z] = None @@ -723,6 +723,7 @@ object JsonCodec { } catch { case _: Exception => rr.rewind() + if (result.isEmpty && it.hasNext) rr = RecordingReader(rr) } } diff --git a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala index 243ef029e..923c19da5 100644 --- a/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala +++ b/zio-schema-json/shared/src/test/scala-2/zio/schema/codec/JsonCodecSpec.scala @@ -1184,6 +1184,18 @@ object JsonCodecSpec extends ZIOSpecDefault { Enumeration2(BooleanValue2(false)) ) }, + test("ADT with noDiscriminator") { + assertEncodesThenDecodes( + Schema[Enumeration3], + Enumeration3(StringValue3("foo")) + ) &> assertEncodesThenDecodes( + Schema[Enumeration3], + Enumeration3(StringValue3Multi("foo", "bar")) + ) &> assertEncodesThenDecodes(Schema[Enumeration3], Enumeration3(IntValue3(-1))) &> assertEncodesThenDecodes( + Schema[Enumeration3], + Enumeration3(BooleanValue3(false)) + ) &> assertEncodesThenDecodes(Schema[Enumeration3], Enumeration3(Nested(StringValue3("foo")))) + }, test("of case classes with discriminator") { assertEncodesThenDecodes(Schema[Command], Command.Cash) &> assertEncodesThenDecodes(Schema[Command], Command.Buy(100)) @@ -1673,6 +1685,20 @@ object JsonCodecSpec extends ZIOSpecDefault { implicit val schema: Schema[Enumeration2] = DeriveSchema.gen[Enumeration2] } + @noDiscriminator + sealed trait OneOf3 + case class StringValue3(value: String) extends OneOf3 + case class IntValue3(value: Int) extends OneOf3 + case class BooleanValue3(value: Boolean) extends OneOf3 + case class StringValue3Multi(value1: String, value2: String) extends OneOf3 + case class Nested(oneOf: OneOf3) extends OneOf3 + + case class Enumeration3(oneOf: OneOf3) + + object Enumeration3 { + implicit val schema: Schema[Enumeration3] = DeriveSchema.gen[Enumeration3] + } + sealed trait Color object Color {