How are value classes handled polymorphically with...
# serialization
z
How are value classes handled polymorphically with JSON serialization? I'm running into an issue. Code will be in thread, but basically, I have an open interface hierarchy, where one of the subclasses is a value class. The top level of the hierarchy is used as a property in a serializable class. Serializing is fine, deserialization is where the issue appears. When the class is
value class
, I get an error saying
Expected JsonObject, but had JsonLiteral as the serialized body of kotlinx.serialization.Polymorphic<Name> at element: $.name
. If I switch it to a
data class
it works better. MVCE here: https://pl.kotl.in/ojKxHZshW
Copy code
interface Name

interface Text : Name

@JvmInline
@Serializable
value class SerializableText(val string: String) : Text

@Serializable
data class SerializablePilot(val name: Name)

val testPilot = SerializablePilot(SerializableText("asdf"))
This serializes to
Copy code
{
  "type": "games.studiohummingbird.voyd.pilot.SerializablePilot",
  "name": "asdf"
}
The SerializersModule is registered like
Copy code
SerializersModule {
    polymorphic(Name::class) {
        subclass(SerializableText::class)
    }
    polymorphic(Text::class) {
        subclass(SerializableText::class)
    }
}
The
data class
serialization is a bit bulkier
Copy code
{
  "type": "games.studiohummingbird.voyd.pilot.SerializablePilot",
  "name": {
    "type": "games.studiohummingbird.skhema.datatypes.serializable.SerializableText",
    "string": "asdf"
  }
}
a
You'll have to create a custom serializer. Currently, when the serializer tries to decode
val name: Name
, it sees that
Name
is an interface, and so it needs the JSON to have a
"type": "..."
property to determine which
Name
implementation to decode. But the actual value is just a string, because
InlineSerializableText
is a value class, so it can't have a
"type"
property.