https://kotlinlang.org logo
#kmongo
Title
# kmongo
r

rocketraman

02/17/2022, 3:00 AM
Trying to save
Point
(GeoJSON) data using kotlinx-serialization... I see Mongo has a
com.mongodb.client.model.geojson.Point
type, but kmongo doesn't recognize it.
Custom serializer like this solved it:
Copy code
object PointSerializer: KSerializer<Point> {
  @OptIn(InternalSerializationApi::class)
  override val descriptor: SerialDescriptor = buildClassSerialDescriptor("Point") {
    element<String>("type")
    element("coordinates", PositionSerializer::descriptor.get())
  }

  override fun serialize(encoder: Encoder, value: Point) {
    encoder.encodeStructure(descriptor) {
      encodeStringElement(descriptor, 0, "Point")
      encodeSerializableElement(descriptor, 1, PositionSerializer, value.coordinates)
    }
  }

  override fun deserialize(decoder: Decoder): Point =
    decoder.decodeStructure(descriptor) {
      var coordinates: Position? = null
      while (true) {
        when (val index = decodeElementIndex(descriptor)) {
          0 -> decodeStringElement(descriptor, 0)
          1 -> coordinates = decodeSerializableElement(descriptor, 1, PositionSerializer)
          CompositeDecoder.DECODE_DONE -> break
          else -> error("Unexpected index: $index")
        }
      }
      Point(coordinates!!)
    }
}

object PositionSerializer: KSerializer<Position> {
  private val delegateSerializer = DoubleArraySerializer()
  override val descriptor = SerialDescriptor("Position", delegateSerializer.descriptor)

  override fun serialize(encoder: Encoder, value: Position) {
    encoder.encodeSerializableValue(delegateSerializer, value.values.toDoubleArray())
  }

  override fun deserialize(decoder: Decoder): Position =
    Position(decoder.decodeSerializableValue(delegateSerializer).toList())
}
53 Views