From 8d7998ebddcbb76c6f264d1148fdade1a3a00ba7 Mon Sep 17 00:00:00 2001 From: Jisoo Park Date: Tue, 17 Sep 2024 17:47:10 +0900 Subject: [PATCH] Respect discriminators of object enums in Scala 3 --- .../shared/src/main/scala-3/zio/json/macros.scala | 4 ++-- .../test/scala-3/zio/json/DerivedDecoderSpec.scala | 12 ++++++++++++ .../test/scala-3/zio/json/DerivedEncoderSpec.scala | 11 +++++++++++ 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/zio-json/shared/src/main/scala-3/zio/json/macros.scala b/zio-json/shared/src/main/scala-3/zio/json/macros.scala index 3392d476..f5f04c4c 100644 --- a/zio-json/shared/src/main/scala-3/zio/json/macros.scala +++ b/zio-json/shared/src/main/scala-3/zio/json/macros.scala @@ -409,7 +409,7 @@ object DeriveJsonDecoder extends Derivation[JsonDecoder] { self => def discrim = ctx.annotations.collectFirst { case jsonDiscriminator(n) => n } - if (isEnumeration) { + if (isEnumeration && discrim.isEmpty) { new JsonDecoder[A] { def unsafeDecode(trace: List[JsonError], in: RetractReader): A = { val typeName = Lexer.string(trace, in).toString() @@ -656,7 +656,7 @@ object DeriveJsonEncoder extends Derivation[JsonEncoder] { self => case jsonDiscriminator(n) => n } - if (isEnumeration) { + if (isEnumeration && discrim.isEmpty) { new JsonEncoder[A] { def unsafeEncode(a: A, indent: Option[Int], out: Write): Unit = { val typeName = ctx.choose(a) { sub => diff --git a/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala b/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala index b7b6379f..b99dd7cd 100644 --- a/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala +++ b/zio-json/shared/src/test/scala-3/zio/json/DerivedDecoderSpec.scala @@ -36,6 +36,18 @@ object DerivedDecoderSpec extends ZIOSpecDefault { assertTrue(result == Right(Foo.Qux)) }, + test("Derives for a sum sealed trait Enumeration type with discriminator") { + @jsonDiscriminator("$type") + sealed trait Foo derives JsonDecoder + object Foo: + case object Bar extends Foo + case object Baz extends Foo + case object Qux extends Foo + + val result = """{"$type":"Qux"}""".fromJson[Foo] + + assertTrue(result == Right(Foo.Qux)) + }, test("Derives for a sum ADT type") { enum Foo derives JsonDecoder: case Bar diff --git a/zio-json/shared/src/test/scala-3/zio/json/DerivedEncoderSpec.scala b/zio-json/shared/src/test/scala-3/zio/json/DerivedEncoderSpec.scala index 2eb329c4..05e28dd6 100644 --- a/zio-json/shared/src/test/scala-3/zio/json/DerivedEncoderSpec.scala +++ b/zio-json/shared/src/test/scala-3/zio/json/DerivedEncoderSpec.scala @@ -24,6 +24,17 @@ object DerivedEncoderSpec extends ZIOSpecDefault { assertTrue(json == """"Qux"""") }, + test("Derives for a sum enum Enumeration type with discriminator") { + @jsonDiscriminator("$type") + enum Foo derives JsonEncoder: + case Bar + case Baz + case Qux + + val json = (Foo.Qux: Foo).toJson + + assertTrue(json == """{"$type":"Qux"}""") + }, test("Derives for a sum sealed trait Enumeration type") { sealed trait Foo derives JsonEncoder object Foo: