0

I am trying to use Kotlin serialization (Kotlin 1.7.2, kotlinx.serialization 1.4.1) for value classes that implement a sealed interface:

@Serializable
sealed interface Power {
    val value: Int
}

@Serializable
@JvmInline
value class PowerWatt(override val value: Int) : Power

@Serializable
@JvmInline
value class PowerHp(override val value: Int) : Power

When attempting serialization to Json, like so:

    @Test
    fun `Correctly serialize and deserialize a value class that implements a sealed interface`() {
        val power: Power = PowerWatt(123)
        val powerSerialized = Json.encodeToString(power)
        val powerDeserialized = Json.decodeFromString<Power>(powerSerialized)
        assertEquals(power, powerDeserialized)
    }

I run into the following error:

kotlinx.serialization.json.internal.JsonDecodingException: Expected class kotlinx.serialization.json.JsonObject as the serialized body of Power, but had class kotlinx.serialization.json.JsonLiteral

    at kotlinx.serialization.json.internal.JsonExceptionsKt.JsonDecodingException(JsonExceptions.kt:24)
    at kotlinx.serialization.json.internal.PolymorphicKt.decodeSerializableValuePolymorphic(Polymorphic.kt:94)
    at kotlinx.serialization.json.internal.StreamingJsonDecoder.decodeSerializableValue(StreamingJsonDecoder.kt:81)
    at kotlinx.serialization.json.Json.decodeFromString(Json.kt:95)

How to make this work? Am I missing something?

Ulrich Schuster
  • 1,670
  • 15
  • 24
  • If you'll insert it into an object it will work as expected. the problem is that you serialize a primitive type of Int into a String - and you get actually an Int. i.e. s: String = "123", which is a Json primitive – A-_-S Nov 30 '22 at 09:07
  • Hm, I don't quite understand this. I do not want to wrap the types into objects (that is, I do not want to use data classes instead of value classes. And I do not see where I explicitly ask for Ints to be serialized as strings, either. – Ulrich Schuster Dec 01 '22 at 19:47

1 Answers1

0

The answer was provided in a Kotlin Serialization GitHub Issue here. For value classes, the wrapped underlying type is serialized directly. Hence, there is not wrapping JSON object where the type field for the polymorphic serializer could be inserted.

Ulrich Schuster
  • 1,670
  • 15
  • 24