-
-
Notifications
You must be signed in to change notification settings - Fork 111
Open
Labels
Description
For some reason, jsoniter was not respecting an Either definition I made and failed with a deserialization error.
I was able to get this Union deserializer to work and thought you might add it to your documentation for the benefit of other users.
Heres an example if you need to use a Union type:
case class AddressRegion(
abbreviatedName: Option[String],
administrativeDivisionCode: Option[String],
isoSubDivisionCode: Option[String],
isoSubDivisionName: Option[String],
name: Option[String]
)
object DataBlocks {
given addressRegionObjectCodec: JsonValueCodec[AddressRegion] = JsonCodecMaker.make
given stringCodec: JsonValueCodec[String] = JsonCodecMaker.make
given unionCodec: JsonValueCodec[String | AddressRegion] = new JsonValueCodec[String | AddressRegion] {
def decode(in: JsonReader): String | AddressRegion = {
// Peek at the next token to determine if it's an object or a string.
in.nextToken() match {
case '{' =>
// If it's an object, try to decode it as AddressRegion
in.rollbackToken() // Rollback the token so the AddressRegion decoder can read it
addressRegionObjectCodec.decodeValue(in, null)
case '"' =>
// If it's a string, decode it as String
in.rollbackToken() // Rollback the token so the String decoder can read it
stringCodec.decodeValue(in, null)
case other =>
// For any other token, it's an unexpected type
throw new RuntimeException(s"Expected JSON object or string, but got token: ${other.toChar}")
}
}
// --- encode method ---
def encode(x: String | AddressRegion, out: JsonWriter): Unit = {
x match {
case s: String => stringCodec .encodeValue(s, out)
case ar: AddressRegion => addressRegionObjectCodec .encodeValue(ar, out)
}
}
override def decodeValue(in: JsonReader, default: String | AddressRegion): String | AddressRegion = {
decode(in)
}
override def encodeValue(x: String | AddressRegion, out: JsonWriter): Unit = {
x match {
case s: String => stringCodec .encodeValue(s, out)
case ar: AddressRegion => addressRegionObjectCodec .encodeValue(ar, out)
}
}
override def nullValue: String | AddressRegion = null
}
given dataBlocksCodec: JsonValueCodec[DataBlocks] = JsonCodecMaker.make
}