Didier Villevalois

    Didier Villevalois

    11 months ago
    Hi! I am trying to use
    JsonContentPolymorphicSerializer
    to manually select what de-serializer to use for my polymorphic class hierarchies, while using
    JsonTransformingSerializer
    to remove the
    type
    fields at serialization. I am doing this:
    inline fun <reified T : Any> noDiscriminatorPolymorphic(crossinline serializerSelector: (element: JsonElement) -> DeserializationStrategy<out T>): KSerializer<T> {
        val serializer = object : JsonContentPolymorphicSerializer<T>(T::class) {
            override fun selectDeserializer(element: JsonElement): DeserializationStrategy<out T> {
                return serializerSelector(element)
            }
        }
        return NoDiscriminantSerializer(serializer)
    }
    
    class NoDiscriminantSerializer<T : Any>(serializer: KSerializer<T>) :
        JsonTransformingSerializer<T>(serializer) {
        override fun transformSerialize(element: JsonElement): JsonElement {
            val content =
                element.jsonObject.mapValues { (_, v) -> if (v is JsonObject) JsonObject(v.jsonObject - "type") else v } - "type"
            return super.transformSerialize(JsonObject(content))
        }
    }
    and then this:
    val myFormat = Json {
        serializersModule = SerializersModule {
            contextual(noDiscriminatorPolymorphic { element ->
                when {
                    "thisField" in element.jsonObject -> ThisClass.serializer()
                    "thatField" in element.jsonObject -> ThatClass.serializer()
                    else -> error("Unknown subclass")
                }
            })
        }
    }
    But the
    type
    fields are always serialized. Does anyone know what I am missing?
    Emil Kantis

    Emil Kantis

    11 months ago
    Is the supertype of ThisClass and ThatClass marked as
    @Serializable
    perhaps?
    Didier Villevalois

    Didier Villevalois

    11 months ago
    Yes, indeed. Thank you @Emil Kantis, that was the tip I needed! I removed the
    @Serializable
    annotation from the supertype, annotated its uses in other
    @Serializable
    with
    @Contextual
    and all rolled as expected. Thank you!
    Emil Kantis

    Emil Kantis

    11 months ago
    You're welcome 🙂