kotlinx.serialization icon indicating copy to clipboard operation
kotlinx.serialization copied to clipboard

Process custom objects as JSON primitives

Open mister-svinia opened this issue 1 year ago • 1 comments

It is possible that I could have missed this in documentation, but nevertheless:

I want to write a custom parser for an object, but i want it to be parsed as a primitive type, not as an object type.

I have a Timestamp parser like this:

@OptIn(ExperimentalSerializationApi::class)
@Serializer(forClass = Timestamp::class)
object TimestampSerializer : KSerializer<Timestamp> {
    override fun deserialize(decoder: Decoder): Timestamp {
        return decoder.decodeStructure(descriptor) {
            Timestamp(decodeLongElement(descriptor, 0) / 1000)
        }
    }

    override fun serialize(encoder: Encoder, value: Timestamp) {
        encoder.encodeStructure(descriptor) {
            encodeLongElement(descriptor, 0, value.toInstant().toEpochMilli() * 1000L)
        }
    }
}

My server stores Timestamp type as an integer - the number of microseconds (6 digits after the dot) since the UNIX epoch. I don't really understand what the code does, but that's not the point - this parser expects json object and does not accept plain numbers.

Once again, I may have missed something in the documentation, and I will be glad if you tell me where to look.

mister-svinia avatar Feb 20 '24 12:02 mister-svinia

@mister-proger You are using the @Serializer annotation which in your case generates the serialDescriptor as it would for a timestamp (as a structure, not a primitive). What you need to do is to override serialDescriptor to be initialised with a PrimitiveSerialDescriptor (with the name (e.g. "my.package.Timestamp") and concrete type - PrimitiveKind.LONG)

pdvrieze avatar Feb 20 '24 14:02 pdvrieze

Thank you very much! I really didn't notice it head-on, and IDEA was silent, which is very strange. Just in case, I'll attach a link to the sample code from the documentation:

https://kotlinlang.org/api/kotlinx.serialization/kotlinx-serialization-core/kotlinx.serialization.descriptors/-primitive-serial-descriptor.html

mister-svinia avatar Feb 21 '24 12:02 mister-svinia

and IDEA was silent, which is very strange

The plugin will just do what you ask it to, it generates a descriptor, but cannot check that your encode/decode implementations actually ignore that structure and serialize as a primitive.

pdvrieze avatar Feb 21 '24 18:02 pdvrieze