I have a Kotlin class representing some control data:
@Serializable(with = ControlSerializer::class)
class ControlData(
val start: Double,
val end: Double,
val offset: Double?,
val ramp: Double?,
)
Which should be deserialized from one of two JSON formats:
{ "control": {
"start": 0.5,
"end": 1.0,
"offset": 3.0,
"ramp": 2.0
}
}
or
{ "control": 2.0 }
In the second format, the single float value should be expanded into start and end, with offset and ramp set to null.
I managed to get this to work using a JsonContentPolymorphicSerializer that selects a specific serializer based on the JSON type, but as the default serializer is not generated I needed to reimplement it:
object ControlSerializer: JsonContentPolymorphicSerializer(ControlData::class) {
override fun selectDeserializer(content: JsonElement) {
return when(content) {
is JsonPrimitive -> FloatSerializer
is JsonObject -> ObjectSerializer
else -> throw Exception("Unrecognized data type")
}
}
}
object FloatSerializer: KSerializer<ControlData> {
// Removed for brevity, but simple serialize/deserialize methods that use encodeDouble()
// and decodeDouble()
}
object ObjectSerializer: KSerializer<ControlData> {
// Also removed for brevity, but a more complicated class that uses
// CompositeDecoder.decodeElementIndex to manually extract every element, which feels
// unnecessarily complicated when the serialization package normally handles this by default
}
My question now is twofold:
- Is there a way to access the default serializer for a class after setting up a custom serializer, so I don’t have to reimplement it manually?
- In deference to the XY problem, is there a better way to achieve what I’m trying to do? I suspect there may be, but I haven’t been able to figure out what it might be.
Ideally I’d like the logic to be contained within the serializers so I don’t have to construct a custom Json object, but I realise this may not be possible. Currently I only need to deserialize data.
Thank you!
fill1890 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.