You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have the suspicion that the incorrect SerialName is used when using a delegate serializer on a class implementing a sealed interface.
This could just be a configuration issue, but after carefully reading the doc, I cannot figure out what I am doing wrong.
I am trying to build a sealed class hierarchy to read/write those here, only I want each individual data of the variant to be represented by a data class (for reuse, the same fields are used across several places with different "tag" discriminators depending on other factors)
@Serializable
data class MyReusedClass(
val aField: String,
val anotherField: UInt
)
@Serializable
@JsonClassDiscriminator("tag")
sealed interface MySealedInterface {
@Serializable
@SerialName("A")
data object A : MySealedInterface // Works as you would expect
@Serializable
@SerialName("B")
data class B(val field1: String) : MySealedInterface // Works as you would expect
@Serializable(with = C.Serializer::class) // Delegating the serializer to `value` doesn't work here, the wrong "tag" is included
data class C(val value: MyReusedClass) : MySealedInterface {
object Serializer : KSerializer<C> {
private val delegateSerializer = MyReusedClass.serializer()
override val descriptor =
SerialDescriptor("C", delegateSerializer.descriptor) // The serialName is supposed to be "C"
override fun serialize(encoder: Encoder, value: C) {
encoder.encodeSerializableValue(delegateSerializer, value.value)
}
override fun deserialize(decoder: Decoder): C {
return C(decoder.decodeSerializableValue(delegateSerializer))
}
}
}
}
Expected behavior
When serializing MySealedInterface.C(MyReusedClass("someString", 42u)) into JSON, I get {"tag": "C", "aField": "someString", "anotherField": 42}
Actual behavior
When serializing MySealedInterface.C(MyReusedClass("someString", 42u)) into JSON, I get {"tag": "my.package.name.MyReusedClass", "aField": "someString", "anotherField": 42}
Environment
Kotlin version: 1.9.10
Library version: 1.6.0
Kotlin platforms: Android
Gradle version: 8.0
IDE version: Android Studio 2022.3.1 Patch 1
The text was updated successfully, but these errors were encountered:
Yes, it is a bug. It is related to the fact that serial name is written inside a beginStructure call, that happens inside encodeSerializableValue(delegateSerializer), so delegateSerializer.serialName is used instead of the "C". Probably related to #2451 and #2288
Uh oh!
There was an error while loading. Please reload this page.
Describe the bug
I have the suspicion that the incorrect SerialName is used when using a delegate serializer on a class implementing a sealed interface.
This could just be a configuration issue, but after carefully reading the doc, I cannot figure out what I am doing wrong.
To Reproduce
I have JSONs of the form
I am trying to build a sealed class hierarchy to read/write those here, only I want each individual data of the variant to be represented by a
data class
(for reuse, the same fields are used across several places with different "tag" discriminators depending on other factors)Expected behavior
When serializing
MySealedInterface.C(MyReusedClass("someString", 42u))
into JSON, I get{"tag": "C", "aField": "someString", "anotherField": 42}
Actual behavior
When serializing
MySealedInterface.C(MyReusedClass("someString", 42u))
into JSON, I get{"tag": "my.package.name.MyReusedClass", "aField": "someString", "anotherField": 42}
Environment
The text was updated successfully, but these errors were encountered: