encodeToString produces wrong indentation for case when there are nested List among the tree
vlsi opened this issue · comments
Vladimir Sitnikov commented
class NestedListsTest {
@Serializable
data class Wrapper(
val elements: List<Element>
)
@Serializable
data class Element(
val name: String,
val subElements: List<SubElement>
)
@Serializable
data class SubElement(
val name: String,
val description: String,
)
@Test
fun test() {
val data = Wrapper(
elements = listOf(
Element(
name = "element 1",
subElements = listOf(
SubElement("1.1", "d1.1"),
SubElement("1.2", "d1.2"),
)
),
)
)
val serialized = Toml.encodeToString(data)
Assert.assertEquals(
serialized,
"""
[[elements]]
name = "element 1"
[[elements.subElements]]
name = "1.1"
description = "d1.1"
[[elements.subElements]]
name = "1.2"
description = "d1.2"
""".trimIndent()
)
val deserialized = Toml.decodeFromString<Wrapper>(serialized)
Assert.assertEquals(data, deserialized)
}
}
com.akuleshov7:ktoml-core:0.5.1
yields
[[elements]]
name = "element 1"
[[elements.subElements]]
name = "1.1"
description = "d1.1"
[[elements.subElements]]
name = "1.2"
description = "d1.2"
The generated TOML does not parse. It would be nice if the error message included the problematic field name or something like that. Currently the error message provides little to no clue on why the parsing went wrong:
com.akuleshov7.ktoml.exceptions.MissingRequiredPropertyException: Invalid number of key-value arguments provided in the input for deserialization. Missing required property <0> from class <kotlin.collections.ArrayList> in the input. (In your deserialization class you have declared this field, but it is missing in the input)
at app//com.akuleshov7.ktoml.decoders.TomlMainDecoder.checkMissingRequiredProperties(TomlMainDecoder.kt:200)
at app//com.akuleshov7.ktoml.decoders.TomlMainDecoder.iterateOverTomlStructure(TomlMainDecoder.kt:258)
at app//com.akuleshov7.ktoml.decoders.TomlMainDecoder.beginStructure(TomlMainDecoder.kt:220)
at app//kotlinx.serialization.internal.AbstractCollectionSerializer.merge(CollectionSerializers.kt:29)
at app//kotlinx.serialization.internal.AbstractCollectionSerializer.deserialize(CollectionSerializers.kt:43)
at app//kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:257)
at app//kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
at app//com.akuleshov7.ktoml.decoders.TomlAbstractDecoder.decodeSerializableValue(TomlAbstractDecoder.kt:96)
at app//kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:43)
at app//kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableElement(AbstractDecoder.kt:70)
at app//com.example.NestedListsTest$Wrapper$$serializer.deserialize(TomlTest.kt:11)
at app//com.example.NestedListsTest$Wrapper$$serializer.deserialize(TomlTest.kt:11)
at app//kotlinx.serialization.encoding.Decoder$DefaultImpls.decodeSerializableValue(Decoding.kt:257)
at app//kotlinx.serialization.encoding.AbstractDecoder.decodeSerializableValue(AbstractDecoder.kt:16)
at app//com.akuleshov7.ktoml.decoders.TomlAbstractDecoder.decodeSerializableValue(TomlAbstractDecoder.kt:96)
at app//com.akuleshov7.ktoml.decoders.TomlMainDecoder$Companion.decode(TomlMainDecoder.kt:293)
at app//com.akuleshov7.ktoml.Toml.decodeFromString(Toml.kt:47)
at app//com.example.NestedListsTest.test(TomlTest.kt:66)
Vladimir Sitnikov commented
In case you wonder,
@Serializable
data class Wrapper(
val elements: List<Element>
)
@Serializable
data class Element(
val name: String,
val subElements: List<SubElement>
)
@Serializable
data class SubElement(
val name: String,
val description: String,
val subSubElements: List<SubSubElement>,
)
@Serializable
data class SubSubElement(
val name: String,
val description: String,
)
with
val data = Wrapper(
elements = listOf(
Element(
name = "element 1",
subElements = listOf(
SubElement(
"1.1", "d1.1",
subSubElements =
listOf(
SubSubElement("1.1.1", "d1.1.1"),
SubSubElement("1.1.2", "d1.1.2")
)
),
SubElement(
"1.2", "d1.2",
subSubElements =
listOf(
SubSubElement("1.2.1", "d1.2.1"),
SubSubElement("1.2.2", "d1.2.2"),
)
),
)
),
Element(
name = "element 2",
subElements = listOf(
SubElement(
"2.1", "d2.1",
subSubElements =
listOf(
SubSubElement("2.1.1", "d2.1.1"),
SubSubElement("2.1.2", "d2.1.2"),
)
),
SubElement(
"2.2", "d2.2",
subSubElements =
listOf(
SubSubElement("2.2.1", "d2.2.1"),
SubSubElement("2.2.2", "d2.2.2"),
)
),
)
),
)
)
yields
[[elements]]
name = "element 1"
[[elements.subElements]]
name = "1.1"
description = "d1.1"
[[elements.subElements.subSubElements]]
name = "1.1.1"
description = "d1.1.1"
[[elements.subElements.subSubElements]]
name = "1.1.2"
description = "d1.1.2"
[[elements.subElements]]
name = "1.2"
description = "d1.2"
[[elements.subElements.subSubElements]]
name = "1.2.1"
description = "d1.2.1"
[[elements.subElements.subSubElements]]
name = "1.2.2"
description = "d1.2.2"
[[elements]]
name = "element 2"
[[elements.subElements]]
name = "2.1"
description = "d2.1"
[[elements.subElements.subSubElements]]
name = "2.1.1"
description = "d2.1.1"
[[elements.subElements.subSubElements]]
name = "2.1.2"
description = "d2.1.2"
[[elements.subElements]]
name = "2.2"
description = "d2.2"
[[elements.subElements.subSubElements]]
name = "2.2.1"
description = "d2.2.1"
[[elements.subElements.subSubElements]]
name = "2.2.2"
description = "d2.2.2"
Andrey Kuleshov commented
Decoding fails due to ArrayOfTables https://toml.io/en/v1.0.0#array-of-tables . It has mostly a zero support in our lib.
But spacing should be fixed, definitely