-
Notifications
You must be signed in to change notification settings - Fork 666
Closed
Description
Describe the bug
kotlinx.serialization.json.internal.JsonEncodingException: Value of type 'MyId' can't be used in JSON as a key in the map. It should have either primitive or enum kind, but its kind is 'CLASS'. Use 'allowStructuredMapKeys = true' in 'Json {}' builder to convert such maps to [key1, value1, key2, value2,...] arrays.
To Reproduce
@JvmInline
@Serializable
value class MyId(val id: String)
@Serializable
data class MyObject {
val myMap: Map<MyId, Double>? = null
}
Json().decodeFromString(MyObject.serializer(), """{"myMap":{"hello", 1.0}}""")Expected behavior
Since value classes are supposed to be (de)serialized by kotlinx.serialization as their underlying value, I would expect MyId to be usable anywhere that String is normally usable, such as the keys in a map.
Workaround is to use a serializer that mimics what kotlinx.serialization already does for value classes, but explicitly makes it a "primitive", such as:
object MyIdSerializer: KSerializer<MyId> {
override val descriptor = PrimitiveSerialDescriptor("MyId", PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: MyId) {
encoder.encodeString(value.id)
}
override fun deserialize(decoder: Decoder): MyId {
return MyId(decoder.decodeString())
}
}Environment
- Kotlin version: [e.g. 1.5.0]
- Library version: [e.g. 1.2.0]
- Kotlin platforms: JVM, JS, Native
- Gradle version: 4.7
goransh