Skip to content

Commit 3b49167

Browse files
authored
Fix allowing of old class names renamed by caseName annotations in JSON decoders for enums (#775)
1 parent 7ee755e commit 3b49167

File tree

2 files changed

+138
-24
lines changed

2 files changed

+138
-24
lines changed

zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -809,12 +809,8 @@ object JsonCodec {
809809
val caseNameAliases = new mutable.HashMap[String, Schema.Case[Z, Any]]
810810
parentSchema.cases.foreach { case_ =>
811811
val schema = case_.asInstanceOf[Schema.Case[Z, Any]]
812-
caseNameAliases.put(case_.id, schema)
813-
case_.annotations.foreach {
814-
case cna: caseNameAliases => cna.aliases.foreach(a => caseNameAliases.put(a, schema))
815-
case cn: caseName => caseNameAliases.put(cn.name, schema)
816-
case _ =>
817-
}
812+
caseNameAliases.put(case_.caseName, schema)
813+
case_.caseNameAliases.foreach(a => caseNameAliases.put(a, schema))
818814
}
819815

820816
def error(msg: String, trace: List[JsonError]): Nothing =
@@ -876,7 +872,7 @@ object JsonCodec {
876872
if (caseNameAliases.size <= 64) {
877873
val stringMatrix = new StringMatrix(caseNameAliases.keys.toArray)
878874
val cases = caseNameAliases.values.map { case_ =>
879-
(JsonError.ObjectAccess(case_.id), schemaDecoder(case_.schema))
875+
(JsonError.ObjectAccess(case_.caseName), schemaDecoder(case_.schema))
880876
}.toArray
881877
(trace: List[JsonError], in: RetractReader) => {
882878
val lexer = Lexer
@@ -895,7 +891,7 @@ object JsonCodec {
895891
new util.HashMap[String, (JsonError.ObjectAccess, ZJsonDecoder[Any])](caseNameAliases.size * 2)
896892
caseNameAliases.foreach {
897893
case (name, case_) =>
898-
cases.put(name, (JsonError.ObjectAccess(case_.id), schemaDecoder(case_.schema)))
894+
cases.put(name, (JsonError.ObjectAccess(case_.caseName), schemaDecoder(case_.schema)))
899895
}
900896
(trace: List[JsonError], in: RetractReader) => {
901897
val lexer = Lexer
@@ -917,7 +913,7 @@ object JsonCodec {
917913
val discriminatorSpan = JsonError.ObjectAccess(discriminatorName)
918914
val caseMatrix = new StringMatrix(caseNameAliases.keys.toArray)
919915
val cases = caseNameAliases.values.map { case_ =>
920-
(JsonError.ObjectAccess(case_.id), schemaDecoder(case_.schema, discriminator))
916+
(JsonError.ObjectAccess(case_.caseName), schemaDecoder(case_.schema, discriminator))
921917
}.toArray
922918
(trace: List[JsonError], in: RetractReader) => {
923919
val lexer = Lexer
@@ -943,7 +939,7 @@ object JsonCodec {
943939
new util.HashMap[String, (JsonError.ObjectAccess, ZJsonDecoder[Any])](caseNameAliases.size * 2)
944940
caseNameAliases.foreach {
945941
case (name, case_) =>
946-
cases.put(name, (JsonError.ObjectAccess(case_.id), schemaDecoder(case_.schema, discriminator)))
942+
cases.put(name, (JsonError.ObjectAccess(case_.caseName), schemaDecoder(case_.schema, discriminator)))
947943
}
948944
(trace: List[JsonError], in: RetractReader) => {
949945
val lexer = Lexer

zio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec.scala

Lines changed: 132 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import zio.test._
2525
object JsonCodecSpec extends ZIOSpecDefault {
2626

2727
case class Person(name: String, age: Int)
28+
2829
val personSchema: Schema[Person] = DeriveSchema.gen[Person]
2930

3031
def spec: Spec[TestEnvironment, Any] =
@@ -1696,14 +1697,15 @@ object JsonCodecSpec extends ZIOSpecDefault {
16961697
assertDecodes(Schema[Command], Command.Cash, charSequenceToByteChunk("""{"type":"Cash","extraField":1}""")) &>
16971698
assertDecodes(Schema[Command], Command.Cash, charSequenceToByteChunk("""{"extraField":1,"type":"Cash"}"""))
16981699
),
1699-
suite("of case objects")(
1700+
suite("of case objects with less than 64 cases")(
17001701
test("without annotation")(
17011702
assertEncodesThenDecodes(Schema[Color], Color.Red)
17021703
),
17031704
test("with caseName")(
17041705
assertEncodesThenDecodes(Schema[Color], Color.Grass) &>
17051706
assertEncodesJson(Schema[Color], Color.Grass, "\"Green\"") &>
1706-
assertDecodes(Schema[Color], Color.Grass, charSequenceToByteChunk("\"Green\""))
1707+
assertDecodes(Schema[Color], Color.Grass, charSequenceToByteChunk("\"Green\"")) &>
1708+
assertDecodesToError(Schema[Color], "\"Grass\"", JsonError.Message("unrecognized string") :: Nil)
17071709
),
17081710
test("with caseAliases")(
17091711
assertEncodesThenDecodes(Schema[Color], Color.Blue) &>
@@ -1715,6 +1717,24 @@ object JsonCodecSpec extends ZIOSpecDefault {
17151717
test("invalid case")(
17161718
assertDecodesToError(Schema[Color], "\"not a color\"", JsonError.Message("unrecognized string") :: Nil)
17171719
)
1720+
),
1721+
suite("of case objects with 64 cases or more")(
1722+
test("without annotation")(
1723+
assertEncodesThenDecodes(Schema[BigEnum], BigEnum.Case69)
1724+
),
1725+
test("with caseName")(
1726+
assertEncodesThenDecodes(Schema[BigEnum], BigEnum.Case00) &>
1727+
assertEncodesJson(Schema[BigEnum], BigEnum.Case00, "\"Case_00\"") &>
1728+
assertDecodes(Schema[BigEnum], BigEnum.Case00, charSequenceToByteChunk("\"Case_00\"")) &>
1729+
assertDecodesToError(Schema[BigEnum], "\"Case00\"", JsonError.Message("unrecognized string") :: Nil)
1730+
),
1731+
test("with caseAliases")(
1732+
assertEncodesThenDecodes(Schema[BigEnum], BigEnum.Case00) &>
1733+
assertDecodes(Schema[BigEnum], BigEnum.Case00, charSequenceToByteChunk("\"Case-00\""))
1734+
),
1735+
test("invalid case")(
1736+
assertDecodesToError(Schema[BigEnum], "\"CaseXX\"", JsonError.Message("unrecognized string") :: Nil)
1737+
)
17181738
)
17191739
),
17201740
suite("transform")(
@@ -2202,8 +2222,11 @@ object JsonCodecSpec extends ZIOSpecDefault {
22022222
)
22032223

22042224
sealed trait OneOf
2205-
case class StringValue(value: String) extends OneOf
2206-
case class IntValue(value: Int) extends OneOf
2225+
2226+
case class StringValue(value: String) extends OneOf
2227+
2228+
case class IntValue(value: Int) extends OneOf
2229+
22072230
case class BooleanValue(value: Boolean) extends OneOf
22082231

22092232
object OneOf {
@@ -2218,9 +2241,13 @@ object JsonCodecSpec extends ZIOSpecDefault {
22182241

22192242
@discriminatorName("_type")
22202243
sealed trait OneOf2
2221-
case class StringValue2(value: String) extends OneOf2
2222-
case class IntValue2(value: Int) extends OneOf2
2223-
case class BooleanValue2(value: Boolean) extends OneOf2
2244+
2245+
case class StringValue2(value: String) extends OneOf2
2246+
2247+
case class IntValue2(value: Int) extends OneOf2
2248+
2249+
case class BooleanValue2(value: Boolean) extends OneOf2
2250+
22242251
case class `StringValue2-Backticked`(value1: String, value2: String) extends OneOf2
22252252

22262253
case class Enumeration2(oneOf: OneOf2)
@@ -2231,11 +2258,16 @@ object JsonCodecSpec extends ZIOSpecDefault {
22312258

22322259
@noDiscriminator
22332260
sealed trait OneOf3
2234-
case class StringValue3(value: String) extends OneOf3
2235-
case class IntValue3(value: Int) extends OneOf3
2236-
case class BooleanValue3(value: Boolean) extends OneOf3
2261+
2262+
case class StringValue3(value: String) extends OneOf3
2263+
2264+
case class IntValue3(value: Int) extends OneOf3
2265+
2266+
case class BooleanValue3(value: Boolean) extends OneOf3
2267+
22372268
case class `StringValue3-Backticked`(value1: String, value2: String) extends OneOf3
2238-
case class Nested(oneOf: OneOf3) extends OneOf3
2269+
2270+
case class Nested(oneOf: OneOf3) extends OneOf3
22392271

22402272
case class Enumeration3(oneOf: OneOf3)
22412273

@@ -2262,19 +2294,22 @@ object JsonCodecSpec extends ZIOSpecDefault {
22622294

22632295
object Command {
22642296
case class Buy(credits: Int) extends Command
2265-
case object Cash extends Command
2297+
2298+
case object Cash extends Command
22662299

22672300
implicit val schema: Schema[Command] = DeriveSchema.gen[Command]
22682301
}
22692302

22702303
case object Singleton
2304+
22712305
implicit val schemaObject: Schema[Singleton.type] = DeriveSchema.gen[Singleton.type]
22722306

22732307
case class Key(name: String, index: Int)
22742308

22752309
object Key {
22762310
implicit lazy val schema: Schema[Key] = DeriveSchema.gen[Key]
22772311
}
2312+
22782313
case class Value(first: Int, second: Boolean)
22792314

22802315
object Value {
@@ -2326,10 +2361,12 @@ object JsonCodecSpec extends ZIOSpecDefault {
23262361
object Order {
23272362
implicit lazy val schema: Schema[Order] = DeriveSchema.gen[Order]
23282363
}
2364+
23292365
@noDiscriminator sealed trait Prompt
23302366

23312367
object Prompt {
2332-
final case class Single(value: String) extends Prompt
2368+
final case class Single(value: String) extends Prompt
2369+
23332370
final case class Multiple(value: List[String]) extends Prompt
23342371

23352372
implicit lazy val schema: Schema[Prompt] = DeriveSchema.gen[Prompt]
@@ -2505,7 +2542,8 @@ object JsonCodecSpec extends ZIOSpecDefault {
25052542
object Enum23Cases {
25062543
implicit lazy val schema: Schema[Enum23Cases] = DeriveSchema.gen[Enum23Cases]
25072544

2508-
@caseName("NumberOne") @caseNameAliases("One") case class Case1(value: String) extends Enum23Cases
2545+
@caseName("NumberOne")
2546+
@caseNameAliases("One") case class Case1(value: String) extends Enum23Cases
25092547

25102548
case class Case2(value: Int) extends Enum23Cases
25112549

@@ -2563,4 +2601,84 @@ object JsonCodecSpec extends ZIOSpecDefault {
25632601
object BacktickedFieldName {
25642602
implicit val schema: Schema[BacktickedFieldName] = DeriveSchema.gen
25652603
}
2604+
2605+
sealed trait BigEnum
2606+
2607+
object BigEnum {
2608+
2609+
@caseName("Case_00")
2610+
@caseNameAliases("Case-00")
2611+
case object Case00 extends BigEnum
2612+
case object Case01 extends BigEnum
2613+
case object Case02 extends BigEnum
2614+
case object Case03 extends BigEnum
2615+
case object Case04 extends BigEnum
2616+
case object Case05 extends BigEnum
2617+
case object Case06 extends BigEnum
2618+
case object Case07 extends BigEnum
2619+
case object Case08 extends BigEnum
2620+
case object Case09 extends BigEnum
2621+
case object Case10 extends BigEnum
2622+
case object Case11 extends BigEnum
2623+
case object Case12 extends BigEnum
2624+
case object Case13 extends BigEnum
2625+
case object Case14 extends BigEnum
2626+
case object Case15 extends BigEnum
2627+
case object Case16 extends BigEnum
2628+
case object Case17 extends BigEnum
2629+
case object Case18 extends BigEnum
2630+
case object Case19 extends BigEnum
2631+
case object Case20 extends BigEnum
2632+
case object Case21 extends BigEnum
2633+
case object Case22 extends BigEnum
2634+
case object Case23 extends BigEnum
2635+
case object Case24 extends BigEnum
2636+
case object Case25 extends BigEnum
2637+
case object Case26 extends BigEnum
2638+
case object Case27 extends BigEnum
2639+
case object Case28 extends BigEnum
2640+
case object Case29 extends BigEnum
2641+
case object Case30 extends BigEnum
2642+
case object Case31 extends BigEnum
2643+
case object Case32 extends BigEnum
2644+
case object Case33 extends BigEnum
2645+
case object Case34 extends BigEnum
2646+
case object Case35 extends BigEnum
2647+
case object Case36 extends BigEnum
2648+
case object Case37 extends BigEnum
2649+
case object Case38 extends BigEnum
2650+
case object Case39 extends BigEnum
2651+
case object Case40 extends BigEnum
2652+
case object Case41 extends BigEnum
2653+
case object Case42 extends BigEnum
2654+
case object Case43 extends BigEnum
2655+
case object Case44 extends BigEnum
2656+
case object Case45 extends BigEnum
2657+
case object Case46 extends BigEnum
2658+
case object Case47 extends BigEnum
2659+
case object Case48 extends BigEnum
2660+
case object Case49 extends BigEnum
2661+
case object Case50 extends BigEnum
2662+
case object Case51 extends BigEnum
2663+
case object Case52 extends BigEnum
2664+
case object Case53 extends BigEnum
2665+
case object Case54 extends BigEnum
2666+
case object Case55 extends BigEnum
2667+
case object Case56 extends BigEnum
2668+
case object Case57 extends BigEnum
2669+
case object Case58 extends BigEnum
2670+
case object Case59 extends BigEnum
2671+
case object Case60 extends BigEnum
2672+
case object Case61 extends BigEnum
2673+
case object Case62 extends BigEnum
2674+
case object Case63 extends BigEnum
2675+
case object Case64 extends BigEnum
2676+
case object Case65 extends BigEnum
2677+
case object Case66 extends BigEnum
2678+
case object Case67 extends BigEnum
2679+
case object Case68 extends BigEnum
2680+
case object Case69 extends BigEnum
2681+
2682+
implicit val schema: Schema[BigEnum] = DeriveSchema.gen
2683+
}
25662684
}

0 commit comments

Comments
 (0)