-
Notifications
You must be signed in to change notification settings - Fork 652
Description
What is your use-case and why do you need this feature?
With open polymorphism, you can specify a default
serializer in your SerializersModule
to handle unknown discriminator values:
val module = SerializersModule {
polymorphic(Project::class) {
subclass(OwnedProject::class)
default { BasicProject.serializer() }
}
}
(from https://github.com/Kotlin/kotlinx.serialization/blob/master/docs/polymorphism.md)
Here, if the discriminator does not match any known subclass' SerialName, default will be used.
Closed polymorphism (sealed classes) is often preferred because SerializersModule is not needed. However, default serializers become an issue then you would still need to register a default in a serializers module, even though the subclasses (and a potential default) are known at compile time. It would be useful to have a way to statically mark one of the subclasses as a default without the use of a SerializersModule to better support the simplicity of using closed polymorphism.
Describe the solution you'd like
I propose adding an @SerialDefault
annotation (or a similar name) that performs the same function as default
:
@Serializable
sealed class Project {
abstract val name: String
}
@Serializable
@SerialDefault // Any unknown project types will be desearialized into a BasicProject
data class BasicProject(override val name: String, val type: String): Project()
@Serializable
@SerialName("OwnedProject")
data class OwnedProject(override val name: String, val owner: String) : Project()
The expected behaviour would be mostly the same as with open polymorphism: sealedClassSerializer.findPolymorphicSerializerOrNull(decoder, "unknown")
would return the default serializer, but without decoder
necessarily having a default registered in its serializersModule.
This could be implemented with an optional val defaultPolymorphicSerializer: DeserializationStrategy<out T>? = null
field in SealedClassSerializer
, and the implementation of findPolymorphicSerializerOrNull
would have an extra ?: defaultPolymorphicSerializer