Delegate to default Serializer
See original GitHub issueHi,
I’m dealing with an annoying JSON
service which is out of my control.
If a value is unavailable it is expressed as an empty array []
instead of a canonical absence or null
value.
I thought about making a custom JSON
deserialiser and manually check if the value was present or not before delegating it to the default generated deserialiser.
However when defining a custom deserialiser it seems the generated deserialiser is not generated no more.
I made a simple test case here:
public object SomeObjSerializer : KSerializer<SomeObj> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("SomeObj")
override fun serialize(encoder: Encoder, value: SomeObj) {}
override fun deserialize(decoder: Decoder): SomeObj {
val input = decoder as JsonDecoder
val jsonObj = input.decodeJsonElement().jsonObject
return if (jsonObj["value"] is JsonPrimitive) {
//How to delegate to the default generated serializer?
} else {
SomeObj(null)
}
}
}
@Serializable(with = SomeObjSerializer::class)
public data class SomeObj(val value: String?)
public fun main() {
//language=JSON
val someJson = """{"value" : [] }"""
val clazz = Json.decodeFromString<SomeObj>(someJson)
//language=JSON
val someOtherJson = """{"value" : "42" }"""
val clazz2 = Json.decodeFromString<SomeObj>(someOtherJson)
}
Note that this example is a simple use case.
As a temporary solution I made a copy of my object without specifying the custom deserialiser which I reference in my own deserialiser and then map back to my original object.
However that of course does not seem to be a good solution.
public object SomeObjSerializer : KSerializer<SomeObj> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("SomeObj")
override fun serialize(encoder: Encoder, value: SomeObj) {}
override fun deserialize(decoder: Decoder): SomeObj {
val input = decoder as JsonDecoder
val jsonObj = input.decodeJsonElement().jsonObject
return if (jsonObj["value"] is JsonPrimitive) {
val obj = decoder.decodeSerializableValue(CopyOfSomeObjForDelegationPurposedOnly.serializer())
SomeObj(obj.value)
} else {
SomeObj(null)
}
}
}
@Serializable(with = SomeObjSerializer::class)
public data class SomeObj(val value: String?)
@Serializable
public data class CopyOfSomeObjForDelegationPurposedOnly(val value: String)
public fun main() {
//language=JSON
val someJson = """{"value" : [] }"""
val clazz = Json.decodeFromString<SomeObj>(someJson)
//language=JSON
val someOtherJson = """{"value" : "42" }"""
val clazz2 = Json.decodeFromString<SomeObj>(someOtherJson)
}
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:7 (3 by maintainers)
Top GitHub Comments
I think nullable JsonTransformingSerializer is a separate issue, can you please create one?
Unfortunately,
JsonTransformingSerializer
does not currently support nullable types (you can’t write something likeJsonTransformingSerializer<Program?>(Program.serializer().nullable
).