kotlinx.serialization
kotlinx.serialization copied to clipboard
Polymorphism with custom serializer which writes JsonObject outputs incorrect class discriminator
Describe the bug
"type":"kotlin.collections.LinkedHashMap" is an incorrect discriminator and prevents data from de-serialization
To Reproduce
@Serializable
data class ValueHolder<V : Any>(
val someField: Int,
@Polymorphic val value: V,
)
@Serializable
data class DataStructure<V : Any>(
val holders: List<ValueHolder<V>>
)
data class VImpl(val a: String, val b: Int)
class E {
val serializer = object : KSerializer<VImpl> {
override val descriptor: SerialDescriptor =
buildClassSerialDescriptor("VImpl") {
element("a", String.serializer().descriptor)
element("b", Int.serializer().descriptor)
}
override fun deserialize(decoder: Decoder): VImpl {
decoder as JsonDecoder
val jsonObject = decoder.decodeJsonElement() as JsonObject
return VImpl(
(jsonObject["a"] as JsonPrimitive).toString(),
(jsonObject["b"] as JsonPrimitive).int,
)
}
override fun serialize(encoder: Encoder, value: VImpl) {
encoder as JsonEncoder
encoder.encodeJsonElement(
JsonObject(
mapOf(
"a" to JsonPrimitive(value.a),
"b" to JsonPrimitive(value.b)
)
)
)
}
}
@Test
fun main() {
val dataStructure = DataStructure(listOf(ValueHolder(0, VImpl("string", 1))))
val json = Json {
serializersModule = SerializersModule {
polymorphic(Any::class, VImpl::class, serializer)
}
}
val string = json.encodeToString(
DataStructure.serializer(serializer),
dataStructure
)
println(string)
}
}
Expected behavior Data can be deserialized back
Environment
- Kotlin version: 1.9.0
- Library version: 1.6.0