rocketraman
11/29/2021, 6:46 AM@Serializable
sealed class Foo<out T> {
@Serializable
data class Bar<out T>(
val value: T?,
): Foo<T>()
}
Json.encodeToString(Foo.Bar(true))
works, but if it is wrapped inside another Serializable e.g.:
@Serializable
data class Whatever(val foo: Foo<Boolean>)
Json.encodeToString(Whatever(Foo.Bar(true)))
produces the error:
Exception in thread "main" kotlinx.serialization.SerializationException: Class 'Boolean' is not registered for polymorphic serialization in the scope of 'Any'.
Mark the base class as 'sealed' or register the serializer explicitly.
Dominaezzz
11/29/2021, 7:34 AMrocketraman
11/29/2021, 7:54 AMrocketraman
11/29/2021, 7:54 AMDominaezzz
11/29/2021, 9:31 AMrocketraman
11/29/2021, 1:54 PMrocketraman
11/29/2021, 1:59 PMDominaezzz
11/29/2021, 2:41 PMrocketraman
11/29/2021, 2:42 PMrocketraman
11/29/2021, 2:50 PM@Serializable
data class Whatever(@Contextual val foo: Foo<Boolean>)
val format = Json { SerializersModule {
contextual(Foo::class) { args ->
println("args: $args")
// just testing, we know the type arg is Boolean for now
Boolean.serializer()
}
} }
rocketraman
11/29/2021, 2:56 PMval format = Json { SerializersModule {
polymorphic(Any::class) {
subclass(Boolean::class, Boolean.serializer())
}
} }
but this doesn't work either.Dominaezzz
11/29/2021, 4:04 PMrocketraman
11/29/2021, 5:26 PM@Serializable
sealed class Foo<out T> {
@Serializable
data class Bar<out T>(
@Contextual val value: T?,
): Foo<T>()
}
val format = Json { SerializersModule {
contextual(Foo.Bar::class) { args ->
println("args: $args")
Boolean.serializer()
}
} }
If so, no, I tried that and it doesn't work either.Dominaezzz
11/29/2021, 5:29 PMDominaezzz
11/29/2021, 5:29 PMrocketraman
11/29/2021, 5:30 PMrocketraman
11/29/2021, 5:35 PMDominaezzz
11/29/2021, 5:50 PMrocketraman
11/29/2021, 5:52 PMDominaezzz
11/29/2021, 5:53 PMrocketraman
11/29/2021, 5:54 PMFoo
, and I serialize a bunch of different types, one of which is Boolean, but could also be other primitives or data classes. Without generics I'd have to create 3 subclasses per type that is being serialized. Unless I'm missing something.Dominaezzz
11/29/2021, 5:55 PMDominaezzz
11/29/2021, 5:55 PMrocketraman
11/29/2021, 5:56 PMrocketraman
11/29/2021, 6:09 PMDominaezzz
11/29/2021, 6:21 PMrocketraman
11/29/2021, 6:22 PMJson.encodeToString(Foo.Bar(true))
but:
Json.encodeToString(Whatever(Foo.Bar(true)))
does not.rocketraman
11/29/2021, 6:39 PMValueHolder
around the type T, so that T is bound by another sealed class hierarchy instead of just being Any
.
@Serializable
sealed class ValueHolder<T> {
abstract val value: T?
}
@Serializable
data class BooleanValueHolder(override val value: Boolean?): ValueHolder<Boolean>()
@Serializable
sealed class Foo<T> {
@Serializable
data class Bar<T>(
val value: ValueHolder<T>,
): Foo<T>()
}
Then serializing data class Whatever(val foo: Foo<Boolean>)
works as expected.