Kapil Yadav
08/17/2023, 4:39 PMval experienceWidgetList:MutableList<Any> = mutableListOf()
val jsonString = Json.encodeToString(Utils.AnySerializer(),experienceWidgetList)
@OptIn(InternalSerializationApi::class)
@ExperimentalSerializationApi
class AnySerializer: KSerializer<Any> {
override val descriptor: SerialDescriptor = ContextualSerializer(Any::class, null, emptyArray()).descriptor
override fun serialize(encoder: Encoder, value: Any) {
val actualSerializer = encoder.serializersModule.getContextual(value::class) ?: value::class.serializer()
encoder.encodeSerializableValue(actualSerializer as KSerializer<Any>, value)
}
override fun deserialize(decoder: Decoder): Any {
error("Unsupported")
}
}
glureau
08/17/2023, 6:00 PMJson.encodeToString(value)
(no need to specify the serializer)
• getting the serializer automatically is not a good generalisation of the problem : you can have 1 class that extends a sealed class (polymorphism), if you encode the class with the class serializer, you will get a different result that if you encode the class with the sealed class serializer (polymorphism requires a class discriminator field).Kapil Yadav
08/22/2023, 9:15 AMKapil Yadav
08/22/2023, 9:15 AMglureau
08/22/2023, 9:16 AMKapil Yadav
08/22/2023, 9:22 AMKapil Yadav
08/22/2023, 9:23 AM@OptIn(InternalSerializationApi::class)
@ExperimentalSerializationApi
class AnySerializer: KSerializer<Any> {
override val descriptor: SerialDescriptor = ContextualSerializer(Any::class, null, emptyArray()).descriptor
override fun serialize(encoder: Encoder, value: Any) {
val actualSerializer = encoder.serializersModule.getContextual(value::class) ?: value::class.serializer()
encoder.encodeSerializableValue(actualSerializer as KSerializer<Any>, value)
}
override fun deserialize(decoder: Decoder): Any {
error("Unsupported")
}
}
glureau
08/22/2023, 9:30 AMval json = Json {
serializersModule = SerializersModule {
polymorphic(Vehicle::class) {
subclass(Truck::class)
subclass(Tesla::class)
}
}
}
So that later, if you do json.decode<Vehicle>(jsonString), Kotlinx will search for a class denominator then take the subclass that matches, then parse the rest of the data to create the right Vehicle.glureau
08/22/2023, 9:30 AMKapil Yadav
08/22/2023, 12:03 PMglureau
08/22/2023, 12:20 PMSerializer for class 'ArrayList'
was in your initial error, I believe with List<> you should have another errorKapil Yadav
08/22/2023, 12:22 PMKapil Yadav
08/22/2023, 12:31 PMglureau
08/22/2023, 12:35 PMKapil Yadav
08/22/2023, 12:36 PMglureau
08/22/2023, 12:38 PMsealed interface Widget
, the polymorphism will be enabled by default
• if you use multiple modules, then define your polymorphism with all the classes you want to use like in my previous snippet.
Then use json.encodeToString<Widget>(myWidgetInstance)
and this should work fine.glureau
08/22/2023, 12:39 PMglureau
08/22/2023, 12:39 PMKapil Yadav
08/22/2023, 12:49 PMglureau
08/22/2023, 12:53 PMimport kotlinx.serialization.modules.polymorphic
import kotlinx.serialization.modules.subclass
Kapil Yadav
08/22/2023, 1:37 PMKapil Yadav
08/22/2023, 1:37 PM