-
Notifications
You must be signed in to change notification settings - Fork 185
Fix ClassCastException for hierarchical enum JSON encoding #970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Fix ClassCastException for hierarchical enum JSON encoding #970
Conversation
- Add constructEnumCase helper to handle both CaseClass0 and Enum case schemas - Update caseMap and jsonFieldDecoder to use type-safe case construction - Add regression tests for hierarchical sealed trait enums Fixes zio#668
6c77e62 to
d5c847a
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It requires formatting and passing CI checks.
The constructEnumCase should be moved to outer scope of JsonCodec to be accessible from JsonCodec.JsonEncoder and JsonCodec.JsonDecoder. Then .toArray.asInstanceOf[Array[Z]] need to be replaced by .toVector to avoid compilation error due to missing ClassTag[Z].
|
Updated. Thank you for letting me know! I'm still getting the hang of all this. |
|
You made non-needed changes by replacing |
- Move constructEnumCase to outer JsonCodec scope (private, not private[codec]) - Only replace .toArray with .toVector where ClassTag[Z] is required - Fix test API usage (.encodeJson/.decodeJson instead of .encode/.decode)
The Scala 3 DeriveSchema was incorrectly marking hierarchical enums (e.g., Animal > Mammal > Bison) as @simpleEnum because intermediate sealed traits have 0 constructor fields. Root cause: Scala 2's isSimpleEnum check includes `subtypes.forall(_.isCaseClass)` but Scala 3's version only checked field counts without verifying all children are actual case classes/objects. Fix: Add `childrenAreAllCases` check using `Flags.Case` to ensure all direct children are case classes/objects before marking as simpleEnum. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
|
Updated per feedback: removed unrelated simpleEnum changes, scoped constructEnumCase to private[codec], and kept enum-case construction fix only where needed for simple enums. Pushed commit 3fc57a1. |
|
CI fix: updated simple-enum field decoder to avoid ClassTag requirement (toArray[Any].asInstanceOf[Array[Z]]). This resolves the Website job compile error on JsonCodec.scala:955. Commit 9a7048a. |
|
Thank you for the feedback. I'll address this. |
|
Acknowledged. |
|
Thank you for the feedback. I'll address this. |
|
Acknowledged. |
|
Thank you for the feedback. I'll address this. |
|
Acknowledged. |
Fixes #668
Problem
When using JSON codec with auto-derived schemas for hierarchical sealed trait enums (e.g.,
Animal > Mammal > Bison), encoding fails withClassCastException: Schema$Enum1 cannot be cast to Schema$CaseClass0.Root Cause
The
JsonCodecimplementation incorrectly assumed all enum cases haveCaseClass0schemas. However, intermediate sealed traits in hierarchical enums haveEnumschemas, notCaseClass0.Solution
constructEnumCasehelper function that pattern matches on case schema typeCaseClass0andEnumcase schemas correctlyCase.constructmethod for type-safe constructionJsonCodec.scalathat made the incorrect assumptionChanges
zio-schema-json/shared/src/main/scala/zio/schema/codec/JsonCodec.scala: Fix + helper functionzio-schema-json/shared/src/test/scala/zio/schema/codec/JsonCodecSpec668.scala: Regression testsTesting
Added regression test suite covering:
CI will validate compilation and test suite passes.