-
Notifications
You must be signed in to change notification settings - Fork 5
Description
Kotlin/kotlinx.serialization#1906
What is your use-case and why do you need this feature?
I need to use JSON to encode and decode 2d arrays of x/y coordinates
@Serializable data class Coordinates( val x: Int, val y: Int, )By default, the JSON encoding is not size-optimal
{ "x": 1, "y": 2 }Encoding a coordinate as a tuple (a fixed-length array, with fixed types per position, see the TypeScript docs) would make the messages more compact, and save a lot of space and improve processing speeds.
[1, 2]There are other data structures I'd like to encode as well. For example, some information for each coordinate.
@Serializable data class CoordinatesDetails( val x: Int, val y: Int, private val colour: String, private val active: Boolean, ) { ... }Again, this would save a lot of space if I could en/decode it as a tuple
[1, 2, "red", true]{ "x": 1, "y": 2, "colour": "red", "active": true }Describe the solution you'd like
I've created a 'tuple descriptor builder' https://github.com/adamko-dev/kotlinx-serialization-typescript-generator/blob/main/docs/tuples.md
// tuple descriptor builder example @Serializable(with = Coordinates.Serializer::class) data class Coordinates( val x: Int, val y: Int, ) { object Serializer : TupleSerializer<Coordinates>( "Coordinates", { element(Coordinates::x) element(Coordinates::y) } ) { override fun tupleConstructor(elements: Iterator<*>): Coordinates { val x = requireNotNull(elements.next() as? Int) val y = requireNotNull(elements.next() as? Int) return Coordinates(x, y) } } }This is quite finickity though, and also it's bugged. Under the hood it requires
buildSerialDescriptor, becausebuildClassSerialDescriptordoesn't allow setting the structure kind to beLIST.My custom tuple-serializer would be much easier if I could
- retain the plugin-generated serializer Keep access to plugin generated serializer when mark class with @Serializable(with = MySerializer) #1169
- override the serial kind of the plugin-generated descriptor and change it from
CLASStoLIST.Alternatively, it would be even easier if I could tell the compiler plugin to generate a descriptor as usual, except just change the 'kind' of the descriptor.
@Serializable(kind = StructureKind.LIST) data class Coordinates( ...Finally, another option is to add an arg to
buildClassSerialDescriptorpublic fun buildClassSerialDescriptor( serialName: String, serialKind: StructureKind = StructureKind.CLASS, // new arg, with a default vararg typeParameters: SerialDescriptor, builderAction: ClassSerialDescriptorBuilder.() -> Unit = {} ): ...