Austin
07/25/2023, 11:41 PMJsonTransformingSerializer
on a root class? Looking to try to handle JSON Schema additionalProperties: true
by having a hash map be merged with the parent JsonObject with something like
import kotlinx.serialization.KSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonTransformingSerializer
import kotlinx.serialization.json.jsonObject
@Serializable(with = RootSerializer::class)
data class Root(val foo: String, val bar: String, val additionalProperties: Map<String, String>)
object RootSerializer : KSerializer<Root> by AdditionalPropertiesSerializer(Root.serializer())
class AdditionalPropertiesSerializer<T: Any>(serializer: KSerializer<T>) : JsonTransformingSerializer<T>(serializer) {
override fun transformSerialize(element: JsonElement): JsonElement {
if (element is JsonObject) {
val additionalProperties = element["additionalProperties"]
if(additionalProperties != null) {
val entries = element.toMutableMap()
entries.remove("additionalProperties")
additionalProperties.jsonObject.entries.forEach {
entries[it.key] = it.value
}
JsonObject(entries)
} else {
return element
}
}
return element
}
}
fun main() {
Json.encodeToString(Root("Foo", "bar", mapOf("hello" to "world")))
}
but this leads to the exception
Exception in thread "main" java.lang.ExceptionInInitializerError
at Root$Companion.serializer(Example.kt:12)
at ExampleKt.main(Example.kt:42)
at ExampleKt.main(Example.kt)
Caused by: java.lang.NullPointerException: Parameter specified as non-null is null: method AdditionalPropertiesSerializer.<init>, parameter serializer
at AdditionalPropertiesSerializer.<init>(Example.kt)
at RootSerializer.<init>(Example.kt:15)
at RootSerializer.<clinit>(Example.kt)
Austin
07/26/2023, 12:56 AM@Serializable(with = RootSerializer::class)
data class Root(val foo: String, val bar: String, val additionalProperties: Map<String, String>)
@Serializer(Root::class)
object RootGeneratedSerializer : KSerializer<Root>
object RootSerializer : KSerializer<Root> by AdditionalPropertiesSerializer(RootGeneratedSerializer)