Hey folks, is it possible to have value classes se...
# serialization
a
Hey folks, is it possible to have value classes serialized/deserialized as primitive values? I'm trying to encode data to CBOR for exchange between Kotlin - TypeScript and I would like to have restricted number types for the data on the Kotlin side so I use value classes. The problem is that default serializer adds class names to the output (a type discriminator) but I would like to use primitive values or maybe custom tags. Is it possible? For example:
Copy code
@Serializable
sealed interface Wrapper

@Serializable
@JvmInline
value class StringWrapper(val value: String): Wrapper

@Serializable
@JvmInline
value class IntegerWrapper(val value: Int): Wrapper

@Serializable
@JvmInline
@OptIn(ExperimentalSerializationApi::class)
value class BinaryWrapper(@ByteString val value: ByteArray): Wrapper

class DataTreeValueSerializationTest {
    @OptIn(ExperimentalSerializationApi::class, ExperimentalStdlibApi::class)
    @Test
    fun testSerialization() {
        val data = IntegerWrapper(1)
        val serialized = Cbor.encodeToByteArray(Wrapper.serializer(), data)
        println(serialized.toHexString())
        val deserialized = Cbor.decodeFromByteArray(Wrapper.serializer(), serialized)
        assertEquals(data, deserialized)
    }
}
This for example is encoded this way:
Copy code
Diagnostic:
[
	_ "IntegerWrapper",
	1
]


Commented:
  9f                -- Array (streaming)
    6e              -- String, length: 14
      496e746567657257726170706572 -- [0], "IntegerWrapper"
    01              -- [1], 1
    ff              -- BREAK
0x9f6e496e74656765725772617070657201ff
And I would like to have it
[1]
in this case. The interface is sealed and there is only one possible class that corresponds to an integer,
IntegerWrapper
so it should be possible to encode/decode it without any ambiguity. With JSON by the way this doesn't work at all since it encodes the data to "1" in this case but then expects an object on deserialization.
It doesn't look like the deserialization can even be implemented with a custom deserializer - Cbor decoder doesn't expose any sort of
peek
method that would allow to analyze the tag. This makes extending it pretty difficult.
I guess it wouldn't even be possible to implement a custom
CborObject
sort of thing similar to
JsonObject
in the Json decoder because of the same issue