Jilles van Gurp
06/24/2024, 9:36 AMimport kotlinx.serialization.KSerializer
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonNull
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.JsonPrimitive
import kotlinx.serialization.json.boolean
import kotlinx.serialization.json.booleanOrNull
import kotlinx.serialization.json.double
import kotlinx.serialization.json.doubleOrNull
import <http://kotlinx.serialization.json.int|kotlinx.serialization.json.int>
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonObject
val DEFAULT_JSON: Json = Json {
// don't rely on external systems being written in kotlin or even having a language with default
// values the default of false is dangerous
encodeDefaults = true
// save space
prettyPrint = false
// people adding things to the json is OK, we're forward compatible and will just ignore it
isLenient = true
// encoding nulls is meaningless and a waste of space.
explicitNulls = false
// adding new fields is OK even if older clients won't understand it
ignoreUnknownKeys = true
// ignore unknown enum values
coerceInputValues = true
// handle NaN and infinity
allowSpecialFloatingPointValues = true
}
fun jsObject(init: dynamic.() -> Unit): dynamic {
val o = js("{}")
init.invoke(o)
return o
}
fun <T> toJsObject(serializer: KSerializer<T>, obj: T): dynamic {
val element = DEFAULT_JSON.encodeToJsonElement(serializer,obj).jsonObject
return element.toJs()
}
fun <T> fromJsObject(serializer: KSerializer<T>, jsObject: dynamic): T {
val jsonString = JSON.stringify(jsObject)
return DEFAULT_JSON.decodeFromString(serializer, jsonString)
}
fun JsonArray.toJs(): dynamic {
val array: dynamic = js("([])")
forEach { value ->
val jsValue = when(value) {
is JsonObject -> value.toJs()
is JsonArray -> value.toJs()
is JsonPrimitive -> value.toJs()
is JsonNull -> null
}
@Suppress("UnsafeCastFromDynamic")
if(jsValue != null) {
array.push(jsValue)
}
}
return array
}
fun JsonObject.toJs(): dynamic {
val original=this
val o = jsObject {
original.entries.forEach {(key,value) ->
val jsValue = when(value) {
is JsonObject -> value.toJs()
is JsonArray -> value.toJs()
is JsonPrimitive -> value.toJs()
is JsonNull -> null
}
if(jsValue != null) {
this[key] = jsValue
}
}
}
return o
}
fun JsonPrimitive.toJs(): dynamic {
return when {
this.isString -> this.content
this.booleanOrNull != null -> this.boolean
this.intOrNull != null -> <http://this.int|this.int>
this.doubleOrNull != null -> this.double
else -> this.content
}
}
Robert Jaros
06/24/2024, 9:41 AMtoJsObject()
implementation with simple JSON.parse(DEFAULT_JSON.encodeToString(serializer, obj))
?Jilles van Gurp
06/24/2024, 9:46 AMRobert Jaros
06/24/2024, 9:52 AMJilles van Gurp
06/24/2024, 9:59 AMJilles van Gurp
06/24/2024, 9:59 AMJilles van Gurp
06/24/2024, 10:00 AMRobert Jaros
06/24/2024, 10:14 AMJilles van Gurp
06/24/2024, 11:03 AM