Mike Wong
10/02/2024, 4:20 PMKSerializer
for a Sealed Interface, where I would call decoder.decodeString()
in the deserialize-Method and check if it starts with [
. But that throws a JsonDecodingException (Expected JsonPrimitive at ... but found ...)
when it encounters the "Array of Strings" option.
What would be the correct approach for this scenario?Mike Wong
10/02/2024, 4:29 PMDecoder
to a JsonDecoder
and then call decodeJsonElement()
to check if it is a JsonPrimitive
or a JsonArray
?glureau
10/02/2024, 4:33 PMJsonTransformingSerializer
? It allow you to operate on JsonElement directly, nice to play with those weird formats 🙂Mike Wong
10/02/2024, 4:48 PMVampire
10/02/2024, 4:51 PMglureau
10/02/2024, 4:54 PMMike Wong
10/02/2024, 5:23 PM@Serializable(with = EntryValueSerializer::class)
sealed interface EntryValue {
@Serializable
data class Reference(val reference: String) : EntryValue
@Serializable
data class Predefined(val mapping: Map<String, String>) : EntryValue
}
Mike Wong
10/02/2024, 5:25 PM@Serializable
data class EntryRegistry(
val entries: Map<String, EntryValue>,
// More properties
)
Mike Wong
10/02/2024, 5:26 PMoverride fun deserialize(decoder: Decoder): EntryValue {
val jsonDecoder = decoder as? JsonDecoder ?: throw IllegalArgumentException("This class can only be deserialized from JSON")
return when (val jsonElement = jsonDecoder.decodeJsonElement()) {
is JsonPrimitive -> EntryValue.Reference(jsonElement.content)
is JsonObject -> {
EntryValue.Predefined(jsonElement.toMap().mapValues { it.value.jsonPrimitive.content })
}
else -> throw IllegalArgumentException("Excpected either JsonPrimitive or JsonArray but was $jsonElement")
}
}
Since I'm always serializing from/to JSON, the cast to JsonDecoder
should be fine, right?ephemient
10/02/2024, 5:32 PMVampire
10/02/2024, 5:39 PMMike Wong
10/02/2024, 6:07 PMMike Wong
10/02/2024, 6:20 PMExpected class kotlinx.serialization.json.JsonObject as the serialized body of EntryValue.Predefined, but had class kotlinx.serialization.json.JsonArray
Since the serializer for that sealed subclass expects to parse the string or string array into an object