I have trouble creating a `SerializersModule` that...
# serialization
s
I have trouble creating a
SerializersModule
that can serialize any implementation of a generic interface. I have it working by marking the value
@Contextual
but I would really prefer not to have to mark them all as such and only rely on a configuration in the
SerializersModule
. Example code in thread 🧵
Copy code
@Test
    fun boxCanBeSerialized() {
        val jsonStr = jsonFormat.encodeToString(TestObject(DefaultBox("test")))

        assertEquals("""{"box":{"t":"test"}}""", jsonStr)
    }

val jsonFormat = Json {
    prettyPrint = false

    serializersModule = SerializersModule {
        contextual(Box::class) {
            DefaultBoxSerializer(it[0])
        }
    }
}

interface Box<T> {
    fun get(): T
}

@Serializable
class DefaultBox<T>(private val t: T) : Box<T> {
    override fun get(): T = t
}

class DefaultBoxSerializer<R, T : Box<R>>(
    rSerializer: KSerializer<R>,
) : KSerializer<T> {

    private val impl = DefaultBox.serializer(rSerializer)

    override val descriptor: SerialDescriptor
        get() = impl.descriptor

    override fun deserialize(decoder: Decoder): T {
        TODO("Not yet implemented")
    }

    override fun serialize(encoder: Encoder, value: T) {
        encoder.encodeSerializableValue(impl, DefaultBox(value.get()))
    }

}

@Serializable
class TestObject<T>(
    @Contextual // <-- How do I get rid of this ?
    val box: Box<T>,
)
g
Copy code
val jsonFormat = Json {
    prettyPrint = false

    serializersModule = SerializersModule {
        polymorphic(Box::class) {
            subclass(DefaultBox::class)
        }
    }
}
s
I need it to work for unknown concrete implementations
g
contextual
allows to setup a custom serializer for a given class
polymorphic
is used to describe subclasses of an interface
Oh so that you can't
s
ie. the DefaultBox is the "serialization substitute"
g
You can have a default implementation, but you will have to provide a SerializersModule with all subclasses of your interfaces at some point.
s
The thing is I believe I could with
polymorphicDefaultSerializer
except it doesnt provide the generic type `KSerializer`s that contextual does
So I am left wondering how wrong I am. If its simply a feature that hasnt been implemented yet or if I am wrong on a more fundamental level