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 04d7e0642..7bb351ea7 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 @@ -259,12 +259,19 @@ object JsonCodec extends BinaryCodec { case d: discriminatorName => (d, case_.id) } + val caseName = case_ match { + case Schema.Case(id, _, _, _, _, annotations) => + annotations.collectFirst { + case name: caseName => name + }.map(_.name).getOrElse(id) + } + if (discriminatorChunk.isEmpty) out.write('{') val indent_ = bump(indent) pad(indent_, out) if (discriminatorChunk.isEmpty) { - string.encoder.unsafeEncode(JsonFieldEncoder.string.unsafeEncodeField(case_.id), indent_, out) + string.encoder.unsafeEncode(JsonFieldEncoder.string.unsafeEncodeField(caseName), indent_, out) if (indent.isEmpty) out.write(':') else out.write(" : ") } @@ -429,7 +436,10 @@ object JsonCodec extends BinaryCodec { { val caseNameAliases = cases.map { case Schema.Case(name, _, _, _, _, annotations) => - (name, annotations.collectFirst { case a: caseNameAliases => a.aliases.toList }.getOrElse(List.empty)) + (name, annotations.collectFirst { + case a: caseNameAliases => a.aliases.toList + case cn: caseName => List(cn.name) + }.getOrElse(List.empty)) }.toMap Lexer.char(trace, in, '{') if (Lexer.firstField(trace, in)) { 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 b23ea1fb8..3c65ad8b1 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 @@ -14,7 +14,7 @@ import zio.schema._ import zio.schema.annotation._ import zio.schema.codec.DecodeError.ReadError import zio.schema.codec.JsonCodec.JsonEncoder.charSequenceToByteChunk -import zio.schema.codec.JsonCodecSpec.PaymentMethod.CreditCard +import zio.schema.codec.JsonCodecSpec.PaymentMethod.{ CreditCard, WireTransfer } import zio.stream.ZStream import zio.test.Assertion._ import zio.test.TestAspect._ @@ -158,6 +158,13 @@ object JsonCodecSpec extends ZIOSpecDefault { SearchRequestWithTransientField("foo", 10, 20, "bar"), charSequenceToByteChunk("""{"query":"foo","pageNumber":10,"resultPerPage":20}""") ) + }, + test("case name annotation") { + assertEncodes( + PaymentMethod.schema, + WireTransfer("foo", "bar"), + charSequenceToByteChunk("""{"wire_transfer":{"accountNumber":"foo","bankCode":"bar"}}""") + ) } ) ) @@ -268,6 +275,13 @@ object JsonCodecSpec extends ZIOSpecDefault { CreditCard("foo", 12, 2022), charSequenceToByteChunk("""{"cc":{"number":"foo","expirationMonth":12,"expirationYear":2022}}""") ) + }, + test("case name") { + assertDecodes( + PaymentMethod.schema, + WireTransfer("foo", "bar"), + charSequenceToByteChunk("""{"wire_transfer":{"accountNumber":"foo","bankCode":"bar"}}""") + ) } ) ) @@ -1034,7 +1048,8 @@ object JsonCodecSpec extends ZIOSpecDefault { expirationYear: Int ) extends PaymentMethod - final case class WireTransfer(accountNumber: String, bankCode: String) extends PaymentMethod + @caseName("wire_transfer") final case class WireTransfer(accountNumber: String, bankCode: String) + extends PaymentMethod implicit lazy val schema: Schema[PaymentMethod] = DeriveSchema.gen[PaymentMethod] } diff --git a/zio-schema/shared/src/main/scala/zio/schema/annotation/caseName.scala b/zio-schema/shared/src/main/scala/zio/schema/annotation/caseName.scala new file mode 100644 index 000000000..326f32775 --- /dev/null +++ b/zio-schema/shared/src/main/scala/zio/schema/annotation/caseName.scala @@ -0,0 +1,5 @@ +package zio.schema.annotation + +import scala.annotation.StaticAnnotation + +final case class caseName(name: String) extends StaticAnnotation