Open mikehearn opened 2 years ago
@mikehearn I'd be happy to contribute to one. I might even be interested in seeing how such a library could be made to "autoregister"
There isn't one that I'm aware of. We had such plans in the past, but we never implemented it, see the rationale here: https://github.com/Kotlin/kotlinx.serialization/pull/350#discussion_r251471644
The rationale being that people might want features it doesn't have yet?
@mikehearn another issue is that when interacting with external systems (rather than just writing reading its own data) there are different ways to serialize the same type. Especially dates are an issue for that, but other types too.
I'd be happy to contribute to one
We would be happy to accept your contribution! The main rationale behind #350 not getting merged is our lack of time along with pretty minor design questions (e.g. what should and shouldn't be serialized, what serialization form should be used for controversial java.util.Date
and so on).
To avoid redundant work, we can start from just a checklist of what you are interested in contributing with a small description of serialized form in a draft PR, if that works for you.
I might even be interested in seeing how such a library could be made to "autoregister"
We have some very vague plans regarding this that are blocked by our current lack of "resource" concept in klibs. The basic idea is to ship static list of serializers, call it "module" and teach serializer plugin to lookup them.
I'm interested in a common library that would support BigDecimal
and BigInteger
(when #2041 is released).
I think it would really help with using KxS, as the learning curve is very steep at the beginning. Serialising any non-standard type requires quite a lot of investment to understand how to implement custom serialisers.
The point raised in https://github.com/Kotlin/kotlinx.serialization/pull/350#discussion_r251471644 (how should java.io.File
be handled?) could be handled by using the recently added typealias serializaton method
import kotlinx.serialization.*
import kotlinx.serialization.descriptors.*
import kotlinx.serialization.encoding.*
import java.io.File
/** Encodes a File as a string, using [invariantSeparatorsPath] */
typealias FileAsInvariantPath = @Serializable(with = FileAsInvariantStringSerializer::class) File
object FileAsInvariantStringSerializer : KSerializer<File> {
override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("java.io.File", PrimitiveKind.STRING)
override fun deserialize(decoder: Decoder): File = File(decoder.decodeString())
override fun serialize(encoder: Encoder, value: File) = encoder.encodeString(value.invariantSeparatorsPath)
}
This means the serialisation behaviour is explicit and clear, while still being seamless with any existing code. It also gives some good examples that users can copy and adapt to implement their own serializers.
FYI, for Java classes that be constructed from a string, I came up with the rather general approach
/**
* A convenience function for creating a [ToStringSerializer] whose name is derived from the class name.
*/
inline fun <reified T : Any> toStringSerializer(noinline create: (String) -> T): ToStringSerializer<T> =
ToStringSerializer(T::class.java.name, create)
/**
* A serializer with the given serial name that uses [Any] instance's [toString] function for serialization and the
* given [create] function for deserialization.
*/
class ToStringSerializer<T : Any>(serialName: String, private val create: (String) -> T) : KSerializer<T> {
override val descriptor = PrimitiveSerialDescriptor(serialName, PrimitiveKind.STRING)
override fun serialize(encoder: Encoder, value: T) = encoder.encodeString(value.toString())
override fun deserialize(decoder: Decoder) = create(decoder.decodeString())
}
which can be used like
/**
* A (de-)serializer for Java [File] instances from / to strings.
*/
object FileSerializer : KSerializer<File> by toStringSerializer(::File)
or
/**
* A (de-)serializer for Java [URI] instances class from / to strings.
*/
object URISerializer : KSerializer<URI> by toStringSerializer(::URI)
Are there any libraries, community or otherwise, that add serializers for common JDK types like Date, Instant, PublicKey, URI, URL etc? It feels like one should exist by now but there's no mention of such an effort in the docs as far as I can tell.