Custom serializer for dynamic map - possible?

Hi,

I have a type like this one below, and I want to write CustomMapSerializer so that it deals with the fields property by handing the map values to different Serializers, depending on the key.

@Serializable
data class Foo(@Serializable(with=UUIDSerializer::class) 
               val fooID: UUID,
               @Serializable(with=CustomMapSerializer::class)  
               val fields: Map<String, Any?>)

The docs for kotlinx.serialization explain a little about a custom serializer for a compound type like a data class, but I don’t see anything on how to handle a variable sized collection like this.

Is there documentation or example code on this anywhere?

2 Likes

You will have to have a look at the source code for the runtime library. It has the default map serializer that you can copy as much as possible.

Yeah, I was looking at the MapLikeSerializer in CollectionSerializers.kt.

One point of confusion is that the MapLikeSerializer returns a descriptor of type MapLikeDescriptor which has a constant number (2) of sub-descriptors. It would appear that I can’t mimic that, since I only know the number of sub-serializers I’m going to use when I see the object to encode. But, without docs to explain the purpose and meaning of the properties of the SerialDescriptor, like elementCount, it’s difficult to form a plan of attack.

I hope this isn’t considered “finished” documentation by the community/authors. I accept it temporarily for bleeding edge software, but ultimately if you have to read the source to learn to use a non-trivial library, something is wrong.

It’s probably bad style, but you can serialize each element to JsonElement. Then the map of JSON elements can easily be serialized. However, it can’t be deserialized without additional manual parsing.

Probalby it’s not the cleanest solution, but while for JSON it’s quite easy to have a custom serializer, if you want to make it more abstract (so that it works also with CBOR or other serializers) you need something more (especially for deserializing).

Some examples are here: Kotlin Map<String, Any?> (andy Any type in general) (de)serialization tests with both Binary (CBOR) and JSON support · GitHub

I’ve also played a bit more with some more custom serializers (only or both ways) in this lib so maybe you can check it out GMapsParser/CustomSerializers.kt at master · 3v1n0/GMapsParser · GitHub