ktoml
ktoml copied to clipboard
How to deserialise Nested-Tables?
Cheers,
thank you for this library :)
Assuming I have the following case:
@Serializable
data class Animals(
val animals: Map<String, Animal>
)
@Serializable
data class Animal(
val name: String,
val vocal: String
)
@Test
fun `can parse animals`() {
// language=toml
val tomlString = """
[animals."my cat"]
name = "maunz"
vocal = "miau"
[animals."my dog"]
name = "bello"
vocal = "wuff"
""".trimIndent()
val animals = Toml.decodeFromString<Animals>(tomlString)
}
I got the following error:
com.akuleshov7.ktoml.exceptions.IllegalTypeException: Line 1:
You are trying to decode a nested Table animals."my cat" with a <Map> type to some primitive type.
For example:
[a]
[a.b]
a = 2
should be decoded to Map<String, Map<String, Long>>, but not to Map<String, Long>
Firstly, I don't think this error message is correct. "Animal" is not a primitive type, or?
However, when I follow the suggestions and change animals: Map<String, Animal>
to animals: Map<String, Map<String, Animal>>
I didn't get an error, but the types are wrong:
As you can see I got Map<String, Map<String,String>>
.
The other way however works like charm:
@Test
fun `can serialise animals`() {
val animals = Animals(mapOf(
"my cat" to Animal("maunz", "miau"),
"my dog" to Animal("bello", "wuff"),
))
val tomlString = Toml.encodeToString(animals)
println(tomlString)
/* Produces
[animals."my cat"]
name = "maunz"
vocal = "miau"
[animals."my dog"]
name = "bello"
vocal = "wuff"
*/
}
Do I misunderstand something?
Kind regards
Hi! Thank you for your very good question ❤️
Actually by the initial implementation of ktoml we expected to have strict naming schema of the decoded type (where you was not able to use Map, but had to explicitly name your fields like “my dog” and “my cat”):
val `my dog`: Animal
this will work in your case if you know the names of nested tables.
Later due to a number of requests, we decided to add anonymous fields and decode them to a Map. And looks like I forgot to support a corner case: when you don’t know the names of nested tables, but know their type.
It’s a bug, need to fix it…
In your case there is a quick workaround with nested map: Map<String, Map<String, String>
- that should work. Or you may name nested tables explicitly as I pointed above with my dog
example.