How can I create a custom serializer for a string ...
# serialization
m
How can I create a custom serializer for a string value that counts as null if the string is empty? In my case I have a
class UuidSerializer : KSerializer<UUID>
but I want
""
to be decoded as
null
rather than a UUID value.
e
I don't think it's possible, there's issues like https://github.com/Kotlin/kotlinx.serialization/issues/1838 in the issue tracker
h
Copy code
object MyEmptyUuidSerializer : KSerializer<Uuid?> {
    override fun deserialize(decoder: Decoder): Uuid? {
        val uuidString = decoder.decodeString()
        return if (uuidString.isEmpty()) {
            null
        } else {
            Uuid.parse(uuidString)
        }
    }
}
What’s wrong with this custom serializer? 🤔
m
Afaik that won't allow serializing values that are guaranteed non-null, no?
Yeah that isn't allowed:
Type '@Serializable(...) UUID' is non-nullable and therefore can not be serialized with serializer for nullable type 'UuidSerializer'
I did try using a JsonTransformingSerializer:
Copy code
class StringAsNullUuidSerializer : JsonTransformingSerializer<UUID>(UuidSerializer()) {
    override fun transformDeserialize(element: JsonElement): JsonElement {
        if (element is JsonPrimitive && element.jsonPrimitive.contentOrNull == "") return JsonNull
        return element
    }
}
but that errors at runtime with
Copy code
Exception in thread "main" kotlinx.serialization.json.internal.JsonDecodingException: Expected string value for a non-null key 'primitive', got null literal instead at element: $.primitive
h
But how should it work? If the value is empty, what value do you expect to be decoded?
m
I expect it to be decoded as null when it's empty, but there are also fields which are guaranteed non-null.
h
Yeah, so you need to change your Kotlin type to
Uuid?
And use the custom serializer on these fields only
m
so I need a serializer for
UUID
and a duplicate serializer with null support for
UUID?
? That seems kinda convoluted