Skip to content

Commit 53fa3ed

Browse files
committed
Generic Position serializer
Previously it only worked with JSON, now it works with any format supported by kotlinx.serialization
1 parent 812654b commit 53fa3ed

File tree

1 file changed

+20
-30
lines changed

1 file changed

+20
-30
lines changed
Lines changed: 20 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,20 @@
11
package io.github.dellisd.spatialk.geojson.serialization
22

33
import io.github.dellisd.spatialk.geojson.Position
4+
import kotlinx.serialization.ExperimentalSerializationApi
5+
import kotlinx.serialization.InternalSerializationApi
46
import kotlinx.serialization.KSerializer
57
import kotlinx.serialization.SerializationException
8+
import kotlinx.serialization.builtins.ListSerializer
9+
import kotlinx.serialization.builtins.serializer
610
import kotlinx.serialization.descriptors.SerialDescriptor
7-
import kotlinx.serialization.descriptors.StructureKind
8-
import kotlinx.serialization.descriptors.buildSerialDescriptor
11+
import kotlinx.serialization.descriptors.listSerialDescriptor
912
import kotlinx.serialization.encoding.Decoder
1013
import 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
*/
3227
public 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

Comments
 (0)