When trying to serialize an CloseFloatingPointRange\<Double>, Serialization complained:
Exception in thread "main" kotlinx.serialization.SerializationException: Class 'ClosedDoubleRange' is not registered for polymorphic serialization in the scope of 'ClosedFloatingPointRange'.
Mark the base class as 'sealed' or register the serializer explicitly.
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:103)
at kotlinx.serialization.internal.AbstractPolymorphicSerializerKt.throwSubtypeNotRegistered(AbstractPolymorphicSerializer.kt:113)
at kotlinx.serialization.PolymorphicSerializerKt.findPolymorphicSerializer(PolymorphicSerializer.kt:96)
at kotlinx.serialization.json.internal.PolymorphicKt.findActualSerializer(Polymorphic.kt:29)
at kotlinx.serialization.json.internal.PolymorphicKt.access$findActualSerializer(Polymorphic.kt:1)
at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:226)
at kotlinx.serialization.encoding.AbstractEncoder.encodeSerializableElement(AbstractEncoder.kt:84)
at SomeClass.write$Self(AnySerialization.kt)
at SomeClass$$serializer.serialize(AnySerialization.kt)
at SomeClass$$serializer.serialize(AnySerialization.kt:6)
at kotlinx.serialization.json.internal.StreamingJsonEncoder.encodeSerializableValue(StreamingJsonEncoder.kt:223)
at kotlinx.serialization.json.Json.encodeToString(Json.kt:73)
at AnySerializationKt.main(AnySerialization.kt:16)
at AnySerializationKt.main(AnySerialization.kt)
and ClosedDoubleRange is private in Kotlin stdlib. Thus, if I understood correctly, it is impossible to write a custom @Serializer for such classes?
To reproduce this:
```kotlin
@Serializable
data class SomeClass(
val range: ClosedFloatingPointRange
)
val x = Json.encodeToString(SomeClass(0.0.rangeTo(1.0)))
````
Environment
It is completely possible.
E.g. take a look at this serializer:
object CFPRSerializer : KSerializer<ClosedFloatingPointRange<Double>> {
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("kotlin.ranges.DoubleClosedFloatingPointRange") {
element<Double>("start")
element<Double>("endEnclusive")
}
override fun serialize(encoder: Encoder, value: ClosedFloatingPointRange<Double>) {
encoder.encodeStructure(descriptor) {
encodeDoubleElement(descriptor, 0, value.start)
encodeDoubleElement(descriptor, 1, value.endInclusive)
}
}
override fun deserialize(decoder: Decoder): ClosedFloatingPointRange<Double> {
decoder.decodeStructure(descriptor) {
var start: Double? = null
var end: Double? = null
while (true) {
val index = decodeElementIndex(descriptor)
if (index == CompositeDecoder.DECODE_DONE) break
if (index == 0) start = decodeDoubleElement(descriptor, index)
else end = decodeDoubleElement(descriptor, index)
}
if (start == null || end == null) throw SerializationException("...")
return start..end
}
}
}
@Serializable
data class SomeClass(
@Serializable(with = CFPRSerializer::class) val range: ClosedFloatingPointRange<Double>
)
Most helpful comment
It is completely possible.
E.g. take a look at this serializer: