avro-kotlin / avro4k

Avro format support for Kotlin
Apache License 2.0
198 stars 37 forks source link

Can not deserialize map of Sealed classes #127

Closed geomagilles closed 2 years ago

geomagilles commented 2 years ago

Hi, with the following classes

@Serializable
data class TestCommand(
    val statuses: MutableMap<String, Status> = mutableMapOf(),
)

@Serializable
sealed class Status {
    @Serializable
    data class Completed(
        val completionIndex: Int
    ) : Status()

    @Serializable
    data class Failed(
        val failureIndex: Int
    ) : Status()
}

I have an error at deserialization when running:

val msg = TestCommand(mutableMapOf(Pair("0", Status.Completed(0)), Pair("1", Status.Failed(1))))
val ser = TestCommand.serializer()
val byteArray = Avro.default.encodeToByteArray(ser, msg)
val msg2 = Avro.default.decodeFromByteArray(ser, byteArray)
msg shouldBe msg2
java.lang.ClassCastException: class kotlinx.serialization.descriptors.PolymorphicKind$SEALED cannot be cast to class kotlinx.serialization.descriptors.StructureKind (kotlinx.serialization.descriptors.PolymorphicKind$SEALED and kotlinx.serialization.descriptors.StructureKind are in unnamed module of loader 'app')
    at com.github.avrokotlin.avro4k.decoder.MapDecoder.beginStructure(MapDecoder.kt:103)
    at kotlinx.serialization.internal.AbstractPolymorphicSerializer.deserialize(AbstractPolymorphicSerializer.kt:130)
    at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:260)
    at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
    at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
    at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
    at kotlinx.serialization.encoding.CompositeDecoder$DefaultImpls.decodeSerializableElement$default(Decoding.kt:535)
    at kotlinx.serialization.internal.MapLikeSerializer.readElement(CollectionSerializers.kt:111)
    at kotlinx.serialization.internal.MapLikeSerializer.readElement(CollectionSerializers.kt:84)
    at kotlinx.serialization.internal.AbstractCollectionSerializer.readElement$default(CollectionSerializers.kt:51)
    at kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:36)
    at kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
    at kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:260)
    at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
    at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
    at kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
thake commented 2 years ago

@geomagilles thanks for raising this ticket! It was very easy to reproduce the bug using your code example. I've fixed it in the master branch.