-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
KTOR-7620 Make Url class @Serializable and JVM Serializable #4421
Conversation
7c7b289
to
62e380e
Compare
@Suppress("UNCHECKED_CAST") | ||
public actual fun <T : Any> JvmSerializerReplacement(serializer: JvmSerializer<T>, value: T): Any = | ||
DefaultJvmSerializerReplacement(serializer, value) | ||
|
||
@PublishedApi // IMPORTANT: changing the class name would result in serialization incompatibility | ||
internal class DefaultJvmSerializerReplacement<T : Any>( | ||
private var serializer: JvmSerializer<T>?, | ||
private var value: T? | ||
) : Externalizable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should such an API better be integrated as part of the Kotlin stdlib itself or at least in a separate library for reuse in other projects? It could also be useful in kotlinx-datetime: Kotlin/kotlinx-datetime#373
And I'll also add the same code to my open-source lib, too (https://github.com/ensody/ReactiveState-Kotlin).
That's unnecessary duplication in multiple places.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding JvmSreializable
interface, you can vote on this issue:
- KT-48243 Publish
kotlin.io.Serializable
I haven't found any issue proposing multiplatform Externalizable
implementation, so feel free to create one!
62e380e
to
8db09e6
Compare
} | ||
} | ||
|
||
internal object UrlJvmSerializer : JvmSerializer<Url> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just an idea: To make this slightly easier to implement one could also add a reusable serializer which utilizes kotlinx-serialization (e.g. using JSON or BSON or CBOR internally).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this idea! Would you like to implement it in this PR or in a separate one?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A separate one. This should rather happen in kotlinx.serialization, so it's generally reusable.
8db09e6
to
d217ee0
Compare
a65ff10
to
9ae3d49
Compare
6666ecf
to
9057d9f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you tell me why can't we mark it with @serializable from kotlinx.serialization?
This PR is doing that, but that's not enough. On Android many APIs work with anything that's Parcelable/Serializable. Imagine you have some random data class which contains a It's very error-prone and inconvenient to force everyone to check all the attributes of every data class and manually use kotlinx.serialization in many different places to ensure that the data is compatible with the Android API. The better solution is to make all widely used types compatible with For this to be possible, the types that are very commonly used in the UI like |
That sounds good; let's mark parent interfaces with the @osipxd, could you also check? |
} | ||
} | ||
|
||
internal object UrlJvmSerializer : JvmSerializer<Url> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like this idea! Would you like to implement it in this PR or in a separate one?
@Suppress("UNCHECKED_CAST") | ||
public actual fun <T : Any> JvmSerializerReplacement(serializer: JvmSerializer<T>, value: T): Any = | ||
DefaultJvmSerializerReplacement(serializer, value) | ||
|
||
@PublishedApi // IMPORTANT: changing the class name would result in serialization incompatibility | ||
internal class DefaultJvmSerializerReplacement<T : Any>( | ||
private var serializer: JvmSerializer<T>?, | ||
private var value: T? | ||
) : Externalizable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Regarding JvmSreializable
interface, you can vote on this issue:
- KT-48243 Publish
kotlin.io.Serializable
I haven't found any issue proposing multiplatform Externalizable
implementation, so feel free to create one!
In our project we had to define our own UrlSerializer. It would be much nicer to have this in the Ktor library itself, so it works out of the box (similar to how Cookie was recently extended). Also, types like Url and Cookie should be java.io.Serializable. Otherwise Android crashes when using those types as e.g. screen arguments. This happens very quickly when Url is used indirectly as part of a data class where we wanted type safety.
e96bd85
to
3ba2335
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thank you!
In our project we had to define our own UrlSerializer. It would be much nicer to have this in the Ktor library itself, so it works out of the box (similar to how Cookie was recently extended).
Also, types like Url and Cookie should be java.io.Serializable. Otherwise Android crashes when using those types as e.g. screen arguments. This happens very quickly when Url is used indirectly as part of a data class where we wanted type safety.