I'm trying to convert a `JsonObject` to `Map<St...
# serialization
r
I'm trying to convert a
JsonObject
to
Map<String, Any>
, but am stumped on
JsonPrimitive
. It stores all values as
String
, so it doesn't seem possible to get a float/boolean/etc. unless you know its type ahead of time. Is there a (simpler) way to accomplish this?
For example, Vert.x's JsonObject has a
getValue
method which returns the raw type (and stores the raw types in the underlying map). https://github.com/eclipse-vertx/vert.x/blob/3682ec2b1283b1b30751bef2b816cf04c173fd21/src/main/java/io/vertx/core/json/JsonObject.java#L388-L391
e
there's extensions to return different types, `.boolean`/`.double`/`.float`/`.int`/`.long` (and
._OrNull
oh right, you do need to know what you're looking for ahead of time
r
Exactly. You could do a hacky workaround and chain all the
orNull
methods together, but that would be imprecise at best.
e
in any case, JSON itself doesn't have distinct numeric types…
e.g.
1.0
is equivalent to
1
so it seems to me that this would be as accurate as anything could be, without knowing the schema beforehand
Copy code
when {
    jsonPrimitive is JsonNull -> null
    jsonPrimitive.isString -> jsonPrimitive.content
    else -> jsonPrimitive.content.toBooleanStrictOrNull()
        ?: jsonPrimitive.content.toBigDecimal()
}
r
Thanks @ephemient. I've expanded based on your POC. Relevant GitHub issue: https://github.com/Kotlin/kotlinx.serialization/issues/1298#issuecomment-934427378
e
as I alluded to above, guessing int/double based on formatting is not appropriate for JSON, because JSON has no distinction between them and it is completely valid to use 1.0 to represent 1 (int) and vice versa
r
Yeah, that's by no means a perfect or extensive strategy. More of a "I have a specific use case where this reliably works" solution, lol.
349 Views