Kotlin / kotlinx.collections.immutable

Immutable persistent collections for Kotlin
Apache License 2.0
1.13k stars 57 forks source link

Support kotlinx.serialization #63

Open NorbertSandor opened 4 years ago

NorbertSandor commented 4 years ago

My main blocking issue is that https://github.com/Kotlin/kotlinx.serialization is not supported :(

fvasco commented 4 years ago

You can consider to use custom serializers and pack them in a serial module, as a temporary workaround.

jfontsaballs commented 1 year ago

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.

jfontsaballs commented 1 year ago

@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).

har-nick commented 1 year ago

Sorry to necro this, but is this planned at all, or do we need to create custom serializers instead?

StylianosGakis commented 1 year ago

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.

shaqaruden commented 11 months ago

This really should have been completed by now, being 4 years after initial request. This is a fairly important thing to have

qurbonzoda commented 8 months ago

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.

lisonge commented 5 months ago

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

mgroth0 commented 2 months ago

@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.