Mixed map CBOR serialization is failing
Describe the bug When trying to serialize map with values set to different it throws an error: kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
To Reproduce Attach a code snippet or test data if possible.
fun testCBOR() {
val goodMap = mapOf(
1 to 2,
3 to -7,
-1 to 1
)
val badMapIntMixedWithString = mapOf(
1 to 2,
3 to -7,
-1 to 1,
-4 to "hello"
)
val badMapIntMixedWithBytes = mapOf(
1 to 2,
3 to -7,
-1 to 1,
-5 to byteArrayOf(1,2,3,4,5,6,7,8)
)
Cbor.encodeToByteArray(goodMap)
Cbor.encodeToByteArray(badMapIntMixedWithString)
Cbor.encodeToByteArray(badMapIntMixedWithBytes)
}
Full stack
kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
Mark the class as @Serializable or provide the serializer explicitly.
at kotlinx.serialization.internal.Platform_commonKt.serializerNotRegistered(Platform.common.kt:91)
at kotlinx.serialization.internal.PlatformKt.platformSpecificSerializerNotRegistered(Platform.kt:29)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:59)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source:1)
at kotlinx.serialization.SerializersKt__SerializersKt.builtinSerializerOrNull$SerializersKt__SerializersKt(Serializers.kt:79)
at kotlinx.serialization.SerializersKt__SerializersKt.serializerByKTypeImpl$SerializersKt__SerializersKt(Serializers.kt:69)
at kotlinx.serialization.SerializersKt__SerializersKt.serializer(Serializers.kt:54)
at kotlinx.serialization.SerializersKt.serializer(Unknown Source:1)
at uaf.playground.PlaygroundKt.testCBOR(Playground.kt:46)
Expected behavior Serialized output
Environment
- Kotlin version: [e.g. 1.4.10]
- Library version: [e.g. 1.0.1]
- Kotlin platforms: [e.g. JVM, Native, Kotlin]
- Gradle version: [e.g. 4.10]
- IDE version (if bug is related to the IDE) [Android Studio 4.1]
That's because the static type of your map is Map<String, Any>. kotlinx.serialization does not support Any polymorphism out of the box because it may be unpredictable in many ways. I'd recommend to use Map<String, String>. If you still need to use Any, pass MapSerializer(String.serializer(), PolymorphicSerializer(Any::class)) to encodeToByteArray and consult documentation on how to register all the types that you need.
@sandwwraith Might be good idea to write a doc on it. There are a lot of Identity where mixed type maps are used. My current pain point is that I actually need a map, because I need an integer keys, but values are mixed. Classes working just fine