Open NorbertSandor opened 4 years ago
You can consider to use custom serializers and pack them in a serial module, as a temporary workaround.
I'd also like immutable collections to be serializable using https://github.com/Kotlin/kotlinx.serialization.
My use case is that I'm passing information between a Ktor server and a KotlinJS client. I have a shared data model in a multiplatform module and I send and receive data between server and client by serializing classes to JSON and sending it via HTTP calls. I'm using kotlinx.serialization for serialization and deserialization. The classes in the shared module are designed to be immutable and I thought the using immutable collections would just fit nicely until I discovered that they can't be serialized.
Right now I'm using regular Kotlin collections but modifications are more difficult.
@NorbertSandor could you please update the issue title so that it clearly reflects that you are requesting serialization with https://github.com/Kotlin/kotlinx.serialization.
This is not to be confused with Java serialization which seems to be discarded (see #17).
Sorry to necro this, but is this planned at all, or do we need to create custom serializers instead?
I've personally had the best experience by doing this
typealias SerializableImmutableList<T> = @Serializable(ImmutableListSerializer::class) ImmutableList<T>
@Serializer(forClass = ImmutableList::class)
class ImmutableListSerializer<T>(private val dataSerializer: KSerializer<T>) : KSerializer<ImmutableList<T>> {
private class PersistentListDescriptor : SerialDescriptor by serialDescriptor<List<String>>() {
override val serialName: String = "kotlinx.serialization.immutable.ImmutableList"
}
override val descriptor: SerialDescriptor = PersistentListDescriptor()
override fun serialize(encoder: Encoder, value: ImmutableList<T>) {
return ListSerializer(dataSerializer).serialize(encoder, value.toList())
}
override fun deserialize(decoder: Decoder): ImmutableList<T> {
return ListSerializer(dataSerializer).deserialize(decoder).toPersistentList()
}
}
And using this type in all the serializable models, while still downcasting them to ImmutableList for the UI or wherever else where you don't care for this extra information in the type.
But still quite frustrating to have to do this everywhere, without any error at compile time that having an ImmutableList
inside a Serializable data class isn't gonna work by default.
Also no way to make this work on the SerializersModule level, where it could be done once and never again on each usage of the type.
This really should have been completed by now, being 4 years after initial request. This is a fairly important thing to have
This issue is one of our top priorities. Unfortunately, we can't provide you with a timeline at the moment as our resources are limited. You can implement custom serializers as hinted by some participants. Also, we would be very happy to accept PR from contributors.
Thank you for your work first
I use kotlinx.immutable
in androidx.compose
, https://developer.android.com/jetpack/compose/performance/stability#summary
In most cases, my data needs to be transmitted serialized between pages, and It also needs to be stored as file content
this greatly limits kotlinx.immutable
scope of use
Although I can use androidx.compose.runtime.Immutable
, but I hope want to use kotlinx.immutable
@StylianosGakis your workaround is helpful, thank you. I had no idea that an annotation could be used in a typealias like that!
Just noticed when I copied the code that I got this warning:
[EXTERNAL_SERIALIZER_USELESS] @Serializer annotation has no effect on class 'ImmutableListSerializer<T>', because all members of KSerializer are already overridden
So might want to edit your snippet to remove the @Serializer
annotation.
My main blocking issue is that https://github.com/Kotlin/kotlinx.serialization is not supported :(