Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to create custom Serializer for PersistentList? #1908

Closed
dennykurniawan48 opened this issue Apr 21, 2022 · 9 comments
Closed

How to create custom Serializer for PersistentList? #1908

dennykurniawan48 opened this issue Apr 21, 2022 · 9 comments

Comments

@dennykurniawan48
Copy link

I have a list of classes and I need to save it into my datastore, probably related to issue #635.

The code is like so:

@Serializable
data class OrderData(
    @Serializable(with = CartData::class)
    val cartData: PersistentList<CartData> = persistentListOf()
)

and my subclass:

@Serializable
data class CartData(
    val price: double,
    val id: Int,
    val product_name: String,
    var qty: Int,
    val error: Boolean = false,
    val message: String = ""
)

But I got a warning when tried to serialize

@serializable(with = CartData::class)

Type mismatch.
Required:
KClass<out KSerializer<*>>
Found:
KClass

How to solve this problem? Thanks in advance.

@dennykurniawan48
Copy link
Author

dennykurniawan48 commented Apr 21, 2022

Got It the answer is in #1114

But get a new error:

error: incompatible types: Class<PersistentListSerializer> cannot be converted to Class<? extends KSerializer<?>>

Possibly related to bug #685

@sandwwraith
Copy link
Member

If you're using KAPT, then it's #685

@simonalveteg
Copy link

simonalveteg commented Aug 1, 2022

I stumbled upon the same issue, and removing the type parameter from the class name and explicitly specifying a type for the rest solved it for me.

@Serializable
data class AppSettings(
    @Serializable(PersistentListSerializer::class)
    val favoriteApps: PersistentList<String> = persistentListOf()
)

@OptIn(ExperimentalSerializationApi::class)
@kotlinx.serialization.Serializer(forClass = PersistentList::class)
class PersistentListSerializer(private val dataSerializer: KSerializer<String>) : KSerializer<PersistentList<String>> {
    private class PersistentListDescriptor : SerialDescriptor by serialDescriptor<List<String>>() {
        @ExperimentalSerializationApi
        override val serialName: String = "kotlinx.serialization.immutable.persistentList"
    }
    override val descriptor: SerialDescriptor = PersistentListDescriptor()
    override fun serialize(encoder: Encoder, value: PersistentList<String>) {
        return ListSerializer(dataSerializer).serialize(encoder, value.toList())
    }
    override fun deserialize(decoder: Decoder): PersistentList<String> {
        return ListSerializer(dataSerializer).deserialize(decoder).toPersistentList()
    }
}

@realityexpander
Copy link

I stumbled upon the same issue, and removing the type parameter from the class name and explicitly specifying a type for the rest solved it for me.

@Serializable
data class AppSettings(
    @Serializable(PersistentListSerializer::class)
    val favoriteApps: PersistentList<String> = persistentListOf()
)

@OptIn(ExperimentalSerializationApi::class)
@kotlinx.serialization.Serializer(forClass = PersistentList::class)
class PersistentListSerializer(private val dataSerializer: KSerializer<String>) : KSerializer<PersistentList<String>> {
    private class PersistentListDescriptor : SerialDescriptor by serialDescriptor<List<String>>() {
        @ExperimentalSerializationApi
        override val serialName: String = "kotlinx.serialization.immutable.persistentList"
    }
    override val descriptor: SerialDescriptor = PersistentListDescriptor()
    override fun serialize(encoder: Encoder, value: PersistentList<String>) {
        return ListSerializer(dataSerializer).serialize(encoder, value.toList())
    }
    override fun deserialize(decoder: Decoder): PersistentList<String> {
        return ListSerializer(dataSerializer).deserialize(decoder).toPersistentList()
    }
}

So, you would have to create an individual custom serializer for each type of PersistentList, instead of using the generics?

@amustafa98
Copy link

So, you would have to create an individual custom serializer for each type of PersistentList, instead of using the generics?

@simonalveteg
Copy link

So, you would have to create an individual custom serializer for each type of PersistentList, instead of using the generics?

I suppose. I just needed it for one type of Persistent List, so for me that didn't matter, but a better solution should be possible

@realityexpander
Copy link

realityexpander commented Feb 22, 2023 via email

@simonalveteg
Copy link

I don't, the code I posted is a modified version of the code in this issue:
#1114
and I remember reading this medium article when I worked on the project that needed serialization:
https://medium.com/androiddevelopers/datastore-and-kotlin-serialization-8b25bf0be66c

You've probably seen both of those links before, but I'm afraid I can't be of more help than that

@realityexpander
Copy link

realityexpander commented Feb 23, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants