11package io.github.dellisd.spatialk.geojson.serialization
22
33import io.github.dellisd.spatialk.geojson.Position
4+ import kotlinx.serialization.ExperimentalSerializationApi
5+ import kotlinx.serialization.InternalSerializationApi
46import kotlinx.serialization.KSerializer
57import kotlinx.serialization.SerializationException
8+ import kotlinx.serialization.builtins.ListSerializer
9+ import kotlinx.serialization.builtins.serializer
610import kotlinx.serialization.descriptors.SerialDescriptor
7- import kotlinx.serialization.descriptors.StructureKind
8- import kotlinx.serialization.descriptors.buildSerialDescriptor
11+ import kotlinx.serialization.descriptors.listSerialDescriptor
912import kotlinx.serialization.encoding.Decoder
1013import kotlinx.serialization.encoding.Encoder
11- import kotlinx.serialization.json.JsonDecoder
12- import kotlinx.serialization.json.JsonEncoder
13- import kotlinx.serialization.json.add
14- import kotlinx.serialization.json.buildJsonArray
15- import kotlinx.serialization.json.double
16- import kotlinx.serialization.json.jsonArray
17- import kotlinx.serialization.json.jsonPrimitive
1814
1915/* *
2016 * [KSerializer] implementation for implementations of the [Position] interface.
2117 * Serializes a Position down to an array of numbers as specified by GeoJSON.
22- * This serializer only works for converting to and from JSON.
2318 * A position maps to `[longitude, latitude, altitude]`.
2419 *
2520 * A position's [altitude][Position.altitude] is only included in the array if it is not null.
@@ -30,32 +25,27 @@ import kotlinx.serialization.json.jsonPrimitive
3025 * @see Position.Companion.serializer
3126 */
3227public object PositionSerializer : KSerializer<Position> {
33- override val descriptor: SerialDescriptor
34- get() = buildSerialDescriptor(" Position" , StructureKind .LIST )
28+ @OptIn(InternalSerializationApi ::class , ExperimentalSerializationApi ::class )
29+ override val descriptor: SerialDescriptor =
30+ listSerialDescriptor(Double .serializer().descriptor)
3531
3632 override fun deserialize (decoder : Decoder ): Position {
37- val input = decoder as ? JsonDecoder ? : throw SerializationException ( " This class can only be loaded from JSON " )
33+ val list = ListSerializer ( Double .serializer()).deserialize(decoder )
3834
39- val array = input.decodeJsonElement().jsonArray
35+ if (list.size < 2 ) {
36+ throw SerializationException (" Position data requires at least 2 doubles (longitude, latitude). Found: ${list.size} " )
37+ }
4038
41- return Position (
42- array[0 ].jsonPrimitive.double,
43- array[1 ].jsonPrimitive.double,
44- array.getOrNull(2 )?.jsonPrimitive?.double
45- )
39+ return Position (list[0 ], list[1 ], if (list.size > 2 ) list[2 ] else null )
4640 }
4741
4842 override fun serialize (encoder : Encoder , value : Position ) {
49- encoder as ? JsonEncoder ? : throw SerializationException (" This class can only be saved as JSON" )
50-
51- val array = buildJsonArray {
52- add(value.longitude)
53- add(value.latitude)
54- if (value.altitude != null ) {
55- add(value.altitude)
56- }
57- }
58-
59- encoder.encodeJsonElement(array)
43+ ListSerializer (Double .serializer()).serialize(
44+ encoder, mutableListOf (
45+ value.longitude,
46+ value.latitude
47+ ).let { list ->
48+ value.altitude?.let { list.plus(it) } ? : list
49+ })
6050 }
6151}
0 commit comments