I’m trying to encode a sealed class
json.encodeToString(
Filter.NOT(
Filter.Field(
name = "foo", value = "bar"
)
)
)
and output something completely different like
{
"not": {
"foo": "bar"
}
}
to exactly match the expected JSON of an API I’m integrating into.
The data structure is a sealed interface (with and, or, xor, etc, but removed for simplicity):
@Serializable
sealed interface Filter {
...
@Serializable
@SerialName("not")
class NOT(val not: Filter): Filter
@Serializable(with = Field.Companion::class)
data class Field(
val name: String,
val value: String
) : Filter {
companion object : KSerializer<Field> {
override val descriptor: SerialDescriptor
get() = mapSerialDescriptor<String, String>()
override fun serialize(encoder: Encoder, value: Field) {
println(value)
encoder.encodeStructure(mapSerialDescriptor<String, String>()) {
mutableMapOf("a" to "b", value.name to value.value)
}
}
override fun deserialize(decoder: Decoder): Field = TODO()
}
}
If I encodeToString, I currently get:
{
"not": {
"type": "kotlin.collections.HashMap"
}
}
if I remove the custom serializer
{
"not": {
"type": "com.jvaas.testing.model.filter.Filter.Field",
"name": "foo",
"value": "bar"
}
}
So the type should not be there, and name + value should be encoded “name”: “value” instead of “name”: name, “value”: value to achieve
{
"not": {
"foo": "bar"
}
}
Any idea how this can be done?