pseusys
pseusys

Reputation: 607

Kotlin serialization: nested polymorphic module

Recently I've been trying to implement Kotlinx Serialization for polymorphic class hierarchy. I used this guide, however my example was a bit more complex. I had the following class structure:

@Serializable
open class Project(val name: String)

@Serializable
@SerialName("owned")
open class OwnedProject(val owner: String) : Project("kotlin")

@Serializable
@SerialName("owned_owned")
class OwnedOwnedProject(val ownerOwner: String) : OwnedProject("kotlinx.coroutines")

And was trying to deserialize OwnedOwnedProject instance using following code:

val module = SerializersModule {
    polymorphic(Project::class) {
        polymorphic(OwnedProject::class) {
            subclass(OwnedOwnedProject::class)
        }
    }
}

val format = Json { serializersModule = module }

fun main() {
    val str = "{\"type\":\"owned_owned\",\"name\":\"kotlin\",\"owner\":\"kotlinx.coroutines\",\"ownerOwner\":\"kotlinx.coroutines.launch\"}"
    val obj = format.decodeFromString(PolymorphicSerializer(Project::class), str)
    println(obj)
}

However whatever combinations of SerializersModule definition I tried, it always ended up with kotlinx.serialization.json.internal.JsonDecodingException: Polymorphic serializer was not found for class discriminator 'owned_owned' error.

Could you please give me a hint: how to implement SerializersModule for given class structure (deeper than two)? Am I missing something?

Upvotes: 2

Views: 1676

Answers (1)

Joffrey
Joffrey

Reputation: 37869

It seems you would need to register OwnedOwnedProject directly under Project as well, so the serializer knows it's a possible subclass:

val module = SerializersModule {
    polymorphic(Project::class) {
        subclass(OwnedOwnedProject::class)
    }
    polymorphic(OwnedProject::class) {
        subclass(OwnedOwnedProject::class)
    }
}

Upvotes: 1

Related Questions