klaxon icon indicating copy to clipboard operation
klaxon copied to clipboard

Missing support for JSON Map

Open lobodpav opened this issue 3 years ago • 3 comments

Hello,

Trying to deserialize a simple JSON map

{ 
    "1": { "name": "Pavel",  "age": 38 },
    "2": { "name": "Jessie", "age": 72 }
}

without a need to do any extra processing. Something like this:

klaxon.parse<Map<String, Person>>(jsonMap)

Here goes the test I wrote to demonstrate it is possible, but in a bit complicated way. I might be getting it wrong and do something incorrectly. Would you advise, please?

package test

import com.beust.klaxon.JsonObject
import com.beust.klaxon.Klaxon

fun main() {
    testJsonMapWorking()
    testJsonMapFailing()
}

private fun testJsonMapFailing() {
    val klaxon = Klaxon()
    val people = klaxon.parse<Map<String, Person>>(jsonMap)

    assert(people?.size == 2)
    // fails on class com.beust.klaxon.JsonObject cannot be cast to class test.Person
    assert(people?.get("1") == Person("Pavel", 38))
}

private fun testJsonMapWorking() {
    val klaxon = Klaxon()
    val people = klaxon.parse<Map<String, JsonObject>>(jsonMap)
        ?.mapValues { klaxon.parseFromJsonObject<Person>(it.value) }

    assert(people?.size == 2)
    assert(people?.get("1") == Person("Pavel", 38))
}

private data class Person(
    val name: String,
    val age: Int?,
)

private val jsonMap = """
{ 
    "1": { "name": "Pavel",  "age": 38 },
    "2": { "name": "Jessie", "age": 72 }
}
""".trimIndent()

lobodpav avatar Jul 31 '21 06:07 lobodpav

You should look at the test MapTest.kt at https://github.com/cbeust/klaxon/blob/master/klaxon/src/test/kotlin/com/beust/klaxon/MapTest.kt

Maybe you did, implies a HashMap should work. The below is a possible solution, not great, but works.

data class First(
    @Json(name = "1")
    val num: Person)
data class Second(
    @Json(name = "2")
    val num: Person)

val r2 = Klaxon().parse<First>(jsonMap)
println(r2?.num?.name)
println(r2?.num?.age)

// Pavel
// 38

AddictArts avatar Dec 02 '21 00:12 AddictArts

Unfortunately, that way won't work in my case. The number of items in the JSON is dynamic and out of my control.

lobodpav avatar Dec 02 '21 07:12 lobodpav

Unfortunately, that way won't work in my case. The number of items in the JSON is dynamic and out of my control.

Understood. I tried the HashMap as it is in the Test, but it didn't work for me, unsure of why. @cbeust any ideas?

AddictArts avatar Dec 02 '21 20:12 AddictArts