Stylianos Gakis
03/06/2024, 4:41 PM@Serializable
data class Outer(val inner: Inner)
@Serializable
@JvmInline
public value class Inner(public val url: String)
I then realized that value classes do not get exported to our iOS target properly, so I am thinking I’d rather just make it not be a value class anymore.
However this then has implications on serialization. For an object like Outer(Inner("someValue"))
Before, with value
keyword:
{
"inner": "someValue"
}
After, without the value
keyword:
{
"inner": {
"url": "someValue"
}
}
Is there a way to still keep the old behavior while not having my class be a value class and therefore not degrade the experience of the iOS target?ephemient
03/06/2024, 10:13 PM@Serializable(with = InnerSerializer::class)
class Inner(val url: String)
object InnerSerializer : KSerializer<Inner> {
override val descriptor: SerialDescriptor = SerialDescriptor("Inner", String.serializer().descriptor)
override fun serialize(encoder: Encoder, value: Inner) = encoder.encodeString(value.url)
override fun deserialize(decoder: Decoder): Inner = Inner(decoder.decodeString())
}
ephemient
03/06/2024, 10:13 PMephemient
03/06/2024, 10:20 PMclass InlineSerializer<Container, Value>(
serialName: String,
private val serializer: KSerializer<Value>,
private val unwrap: (Container) -> Value,
private val wrap: (Value) -> Container,
) : KSerializer<Container> {
override val descriptor: SerialDescriptor = SerialDescriptor(serialName, serializer.descriptor)
override fun serialize(encoder: Encoder, value: Container) = encoder.encodeSerializableValue(serializer, unwrap(value))
override fun deserialize(decoder: Decoder): Container = wrap(decoder.decodeSerializableValue(serializer))
}
object InnerSerializer : KSerializer<Inner> by InlineSerializer("Inner", String.serializer(), Inner::url, ::Inner)
and the latter can be repeated for as many types as you needStylianos Gakis
03/07/2024, 8:00 AM