From b0b7062c3b410c6927afbb48aac5b47ed83ee1df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pablo=20Femen=C3=ADa?= <131800808+pablf@users.noreply.github.com> Date: Sat, 18 Nov 2023 17:05:01 +0100 Subject: [PATCH] fixed decoder for enum with discriminator (#610) Co-authored-by: Daniel Vigovszky --- .../main/scala/zio/schema/codec/JsonCodec.scala | 6 +++--- .../scala-2/zio/schema/codec/JsonCodecSpec.scala | 16 +++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) 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 595f1c408..62f78370c 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 @@ -517,7 +517,7 @@ object JsonCodec { case Schema.Either(left, right, _) => ZJsonDecoder.either(schemaDecoder(left, hasDiscriminator), schemaDecoder(right, hasDiscriminator)) case l @ Schema.Lazy(_) => schemaDecoder(l.schema, hasDiscriminator) //case Schema.Meta(_, _) => astDecoder - case s @ Schema.CaseClass0(_, _, _) => caseClass0Decoder(s) + case s @ Schema.CaseClass0(_, _, _) => caseClass0Decoder(hasDiscriminator, s) case s @ Schema.CaseClass1(_, _, _, _) => caseClass1Decoder(hasDiscriminator, s) case s @ Schema.CaseClass2(_, _, _, _, _) => caseClass2Decoder(hasDiscriminator, s) case s @ Schema.CaseClass3(_, _, _, _, _, _) => caseClass3Decoder(hasDiscriminator, s) @@ -833,8 +833,8 @@ object JsonCodec { private[codec] object ProductDecoder { import zio.schema.codec.JsonCodec.JsonDecoder.schemaDecoder - private[codec] def caseClass0Decoder[Z](schema: Schema.CaseClass0[Z]): ZJsonDecoder[Z] = { (trace: List[JsonError], in: RetractReader) => - val _ = Codecs.unitDecoder.unsafeDecode(trace, in) + private[codec] def caseClass0Decoder[Z](hasDiscriminator: Boolean, schema: Schema.CaseClass0[Z]): ZJsonDecoder[Z] = { (trace: List[JsonError], in: RetractReader) => + if (!hasDiscriminator) Codecs.unitDecoder.unsafeDecode(trace, in) schema.defaultConstruct() } 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 81db36e62..7bdfb9503 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 @@ -243,7 +243,7 @@ object JsonCodecSpec extends ZIOSpecDefault { charSequenceToByteChunk("""{"oneOf":{"_type":"StringValue2","value":"foo2"}}""") ) }, - test("case class ") { + test("case class") { assertEncodes( searchRequestWithTransientFieldSchema, SearchRequestWithTransientField("foo", 10, 20, "bar"), @@ -1027,6 +1027,10 @@ object JsonCodecSpec extends ZIOSpecDefault { Enumeration2(BooleanValue2(false)) ) }, + test("of case classes with discriminator") { + assertEncodesThenDecodes(Schema[Command], Command.Cash) &> + assertEncodesThenDecodes(Schema[Command], Command.Buy(100)) + }, suite("of case objects")( test("without annotation")( assertEncodesThenDecodes(Schema[Color], Color.Red) @@ -1496,6 +1500,16 @@ object JsonCodecSpec extends ZIOSpecDefault { implicit val schema: Schema[Color] = DeriveSchema.gen[Color] } + @annotation.discriminatorName("type") + sealed trait Command + + object Command { + case class Buy(credits: Int) extends Command + case object Cash extends Command + + implicit val schema: Schema[Command] = DeriveSchema.gen[Command] + } + case object Singleton implicit val schemaObject: Schema[Singleton.type] = DeriveSchema.gen[Singleton.type]