Don Kittle
04/26/2023, 5:33 PMEnums cannot be serialized polymorphically with 'type' parameter. You can use 'JsonBuilder.useArrayPolymorphism' instead
My serialization is set up as follows:
val JSON = Json {
ignoreUnknownKeys = true
encodeDefaults = true
explicitNulls = false
}
My enums follow this kind of pattern:
@Serializable
@JsonClassDiscriminator("ItemProperty")
sealed interface ItemProperty {
@Serializable
@SerialName("ArmorProperty")
enum class ArmorProperty : ItemProperty {
@SerialName("Light") Light,
@SerialName("Medium") Medium,
@SerialName("Heavy") Heavy,
@SerialName("Shield") Shield;
}
@Serializable
enum class FocusProperty : ItemProperty {
@SerialName("Arcane") Arcane,
@SerialName("Druidic") Druidic,
@SerialName("HolySymbol") HolySymbol;
}
}
I cannot find anything except a really simple enum example in the serialization documentation.
Does anyone know what I'm doing wrong here? I am unsure what ``JsonBuilder.useArrayPolymorphism` ` is or how to use it to resolve this issue.ephemient
04/26/2023, 5:36 PMJson {
useArrayPolymorphism = true
}
changes the format of polymorphismephemient
04/26/2023, 5:39 PM@Serializable
sealed interface Base {
@Serializable
data class Impl(val value: String)
}
Impl.serializer()
serializes Impl(value = "foo")
as {"value": "foo"}
, and JSON's default polymorphic serialization of Base
takes that and adds a type
discriminator, e.g. {"type": "Impl", "value": "foo"}
. that's only possible with classes/objects, not enumsephemient
04/26/2023, 5:41 PMuseArrayPolymorphism
uses a wrapper array instead of adding a property to the object, e.g. ["Impl", {"value": "foo"}]
, which does work for non-objectsDon Kittle
04/26/2023, 5:50 PMArrayPolymorphism
on the interface/enums and use the Polymorphism
serialization for the data class that uses enums in some of it's properties? If I just the ArrayPolymorphism
for the whole data class (plus it's enum properties), I get an array of one instance of the data class - and that is causing Kmongo to complain...
One of my data classes looks like this, for example:
@Serializable
data class Gear(
val name: String,
val description: String,
...
val properties: List<ItemProperty>
)
Don Kittle
04/26/2023, 5:52 PM@Serializable (with = ArrayPolymorphism)
sealed interface ItemProperty {
...
}
And leave my main json { }
config how it was?
(sorry, I'm just guessing here)ephemient
04/26/2023, 5:55 PMephemient
04/26/2023, 5:55 PMDon Kittle
04/26/2023, 6:06 PMephemient
04/26/2023, 6:45 PMephemient
04/26/2023, 6:50 PMDon Kittle
04/28/2023, 5:41 PMclass.sealedSubclasses
doesn't resolve in common code (only in jvm code).ephemient
04/28/2023, 5:42 PMKClass.sealedSubclasses
worked, KClass.serializer()
wouldn't, since that also relies on JVM reflectionDon Kittle
04/28/2023, 5:43 PM@Serializable
data class SimpleGear(
val name: String,
val description: String,
val weight: Int,
val properties: List<ItemProperty>
)
val longsword = SimpleGear(
"Longsword",
"Hack off heads with this",
3,
listOf(ItemProperty.WeaponProperty.Slashing, ItemProperty.WeaponProperty.Versatile))
val jsonString = JSON.encodeToString(longsword)
println(jsonString)
println("${longsword == JSON.decodeFromString(jsonString)}")
{
"name": "Longsword",
"description": "Hack off heads with this",
"weight": 3,
"properties": [
[
"ca.kittle.model.reference.ItemProperty.WeaponProperty",
"Slashing"
],
[
"ca.kittle.model.reference.ItemProperty.WeaponProperty",
"Versatile"
]
]
}
Don Kittle
04/28/2023, 5:43 PMException in thread "main" kotlinx.serialization.SerializationException: Serializer for class 'Any' is not found.
Please ensure that class is marked as '@Serializable' and that the serialization compiler plugin is applied.
Don Kittle
04/28/2023, 5:44 PMah, and even ifworked,KClass.sealedSubclasses
wouldn't, since that also relies on JVM reflectionKClass.serializer()
ephemient
04/28/2023, 5:44 PMJSON.decodeFromString<SimpleGear>(jsonString)
or
JSON.decodeFromString(SimpleGear.serializer(), jsonString)
since the type is inferred as Any
in the stringDon Kittle
04/28/2023, 5:49 PMDon Kittle
04/28/2023, 5:49 PM