Does polymorphic serializer support sub classes wi...
# serialization
p
Does polymorphic serializer support sub classes with generic type parameters?
Copy code
@Serializable
sealed class Foo<T : Any> {
    @Serializable
    data class Bar<T : Any>(val o: T) : Foo<T>()

    @Serializable
    data class Baz(val o: String) : Foo<String>()
}
It's not possible to do something like
PolymorphicSerializer(Foo::class, UnitSerializer)
.
s
You can probably register serializer for bar like
BarSerializer(PolymorphicSerializer(Any::class))
p
Maybe this snippet will show a more detailed example of the problem I am facing:
Copy code
@Serializable
sealed class Result<T : Any> {
    @Serializable
    data class Success<T : Any>(val result: T) : Result<T>()

    @Serializable
    data class Failure<T : Any>(val error: String) : Result<T>()
}

private inline fun <reified T : Any, reified R : Any> run(data: T): Result<R> {
    val messageSerializer = T::class.serializer()
    val json = jsonSerializer.stringify(messageSerializer, data)

    // Send message...
    // Receive response...

    val response: String // can either be Result.Success<R> or Result.Failure<R>

    // Create both serializers for success and failure
    val successSerializer = Result.Success.serializer(R::class.serializer())
    val failureSerializer = Result.Failure.serializer(R::class.serializer())
    // How to register both these serializers at runtime for Result<R> class? 
    val polymorphicSerializer = PolymorphicSerializer(Result::class)

    return jsonSerializer.parse(polymorphicSerializer, response)
}

private val jsonSerializer by lazy {
    Json(
        configuration = JsonConfiguration.Stable,
        context = SerializersModule {}
    )
}
The only solution I can think of is to create
Json
at runtime with different generic types each time run is called. But I don't know if this is the most effective way to do this.
Copy code
val jsonSerializer = Json(
    configuration = JsonConfiguration.Stable,
    context = SerializersModule {
        include(JsonSerializer.context)
        polymorphic<RpcResponse<R>> {
            addSubclass(RpcResponse.Success.serializer(R::class.serializer()))
            addSubclass(RpcResponse.Failure.serializer(R::class.serializer()))
        }
    }
)
@sandwwraith what do you think about this solution?
s
So you don't really know what `T`s you will have and they can be literally any class? That complicates things, yes. Solution with creating module every time will allocate several extra objects, but it does not consume a lot of time, so this could be probably OK for you
p
So you don't really know what `T`s you will have and they can be literally any class?
Yes that's the case. I can't really register them ahead of time.