Hello all. I'm bumped into issue with kotlin seria...
# serialization
m
Hello all. I'm bumped into issue with kotlin serialization I have wrapper
Copy code
@Serializable
sealed interface OperationResult<T>

@Serializable
class OperationSuccess<T>(val value: T): OperationResult<T>
In case of
OperationSuccess<Goal>
(where
Goal
is my data class) I can register value type for serialization/deserialization using:
Copy code
Json {
  serializersModule = SerializerModule {
    polymorphic(Any::class) {
      subclass(Goal::class)
    }
  }
}
But in case of
OperationSuccess<List<Goal>>
I get runtime error:
Copy code
Class 'SingletonList' is not registered for polymorphic serialization in the scope of 'Any'.
To be registered automatically, class 'SingletonList' has to be '@Serializable', and the base class 'Any' has to be sealed and '@Serializable'.
Alternatively, register the serializer for 'SingletonList' explicitly in a corresponding SerializersModule.
kotlinx.serialization.SerializationException: Class 'SingletonList' is not registered for polymorphic serialization in the scope of 'Any'.
To be registered automatically, class 'SingletonList' has to be '@Serializable', and the base class 'Any' has to be sealed and '@Serializable'.
Alternatively, register the serializer for 'SingletonList' explicitly in a corresponding SerializersModule.
How can I register list serializer as polymorphic for Any? Is there a way to serialize/deserialize wrapper with collection inside?
Oh! I found very beautiful solution.
Copy code
@Serializable(with = OperationResultSerializer::class)
sealed interface OperationResult<T>

@Serializable
class OperationSuccess<T>(val value:T): OperationResult<T>

@Serializable
class OperationFailed(val error: String): OperationResult<Nothing>

@OptIn(InternalSerializationApi::class)
class OperationResultSerializer<T>(valueSerializer: KSerializer<T>): KSerializer<OperationResult<T>> {
    private val serializer = SealedClassSerializer(
        OperationResult::class.simpleName!!,
        OperationResult::class,
        arrayOf(OperationSuccess::class, OperationFailed::class),
        arrayOf(OperationSuccess.serializer(valueSerializer), OperationFailed.serializer())
    )

    override val descriptor: SerialDescriptor = serializer.descriptor
    @Suppress("UNCHECKED_CAST")
    override fun deserialize(decoder: Decoder): OperationResult<T> { return serializer.deserialize(decoder) as OperationResult<T> }
    override fun serialize(encoder: Encoder, value: OperationResult<T>) { serializer.serialize(encoder, value) }
}
All magic are inside of SealedClassSerializer And now serialization/deserialization of
OperationResult<List<Int>>
works perfectly