Repository: orchestr7/ktoml (kotlin)

Issue:
Support decoding of Map<String, List<String>>
> @orchestr7 any idea how can multiple list. list are many. so can not do specific variable for all list
> 
> ```
> [bundles]
> koin-common = [
>     "koin-core",
>     "koin-compose",
>     "koin-compose-viewmodel"
> ]
> 
> ktor-common = [
>     "ktor-client-core",
>     "ktor-client-content-negotiation",
>     "ktor-serialization-kotlinx-json",
>     "ktor-client-auth",
>     "ktor-client-logging"
> ]
> 
> ktor-commond = [
>     "ktor-client-core",
>     "ktor-client-content-negotiation",
>     "ktor-serialization-kotlinx-json",
>     "ktor-client-auth",
>     "ktor-client-loggqing"
> ]
> ```
> i try this code for understanding how looks like but i not understand how can array extract
> ```
> val tomlString = """
> [bundles]
> koin-common = [
>     "koin-core",
>     "koin-compose",
>     "koin-compose-viewmodel"
> ]
> 
> ktor-common = [
>     "ktor-client-core",
>     "ktor-client-content-negotiation",
>     "ktor-serialization-kotlinx-json",
>     "ktor-client-auth",
>     "ktor-client-logging"
> ]
> 
> ktor-commond = [
>     "ktor-client-core",
>     "ktor-client-content-negotiation",
>     "ktor-serialization-kotlinx-json",
>     "ktor-client-auth",
>     "ktor-client-loggqing"
> ]
> """.trimIndent()
> 
> val tomlAST = TomlParser(TomlInputConfig()).parseString(tomlString)
> tomlAST.prettyPrint()
>             
> ```
> 
> this is output 
> ```
>  - TomlFile (rootNode)
>      - TomlTable ([bundles])
>          - TomlKeyValueArray (koin-common=[ "koin-core", "koin-compose", "koin-compose-viewmodel" ])
>          - TomlKeyValueArray (ktor-common=[ "ktor-client-core", "ktor-client-content-negotiation", "ktor-serialization-kotlinx-json", "ktor-client-auth", "ktor-client-logging" ])
>          - TomlKeyValueArray (ktor-commond=[ "ktor-client-core", "ktor-client-content-negotiation", "ktor-serialization-kotlinx-json", "ktor-client-auth", "ktor-client-loggqing" ])
> 
> ```
> how can get bundles list data from tomlstring. any suggestion or solution. thank you
> ```
> @Serializable
> data class VersionCatalog(
>     val bundles: Map<String, List<String>> = emptyMap(),
> )
> 
> private fun versionCatalog(tomlString: String): VersionCatalog =
>         Toml(
>             inputConfig = TomlInputConfig(
>                 ignoreUnknownNames = true,
>             )
>         ).decodeFromString<VersionCatalog>(tomlString)
> 
> ```
> 
>  

 _Originally posted by @Coding-Meet in [#336](https://github.com/orchestr7/ktoml/issues/336#issuecomment-3301251980)_

Pull request:
Fixes #352

Patch:
diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/decoders/TomlMapDecoder.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/decoders/TomlMapDecoder.kt
index 2f9fb711..b779232f 100644
--- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/decoders/TomlMapDecoder.kt
+++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/decoders/TomlMapDecoder.kt
@@ -96,6 +96,11 @@ public class TomlMapDecoder private constructor(
         // stubs are internal technical nodes that are not needed in this scenario
         skipStubs()
         return when (val processedNode = rootNode.children[decodingElementIndex]) {
+            is TomlKeyValueArray -> if (index % 2 == 0) {
+                processedNode.key.toString() as T
+            } else {
+                decodeTomlKeyValueArray(processedNode, deserializer)
+            }
             is TomlKeyValue -> if (index % 2 == 0) {
                 processedNode.key.toString() as T
             } else {
@@ -148,6 +153,11 @@ public class TomlMapDecoder private constructor(
         TomlMainDecoder.decode(deserializer, rootNode, config)
     }
 
+    private fun <T> decodeTomlKeyValueArray(
+        processedNode: TomlKeyValueArray,
+        deserializer: DeserializationStrategy<T>
+    ): T = TomlArrayDecoder.decode(deserializer, processedNode, config)
+
     private fun <T> decodeTomlTable(
         processedNode: TomlTable,
         deserializer: DeserializationStrategy<T>


Test patch:
diff --git a/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/structures/MapDecoderTest.kt b/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/structures/MapDecoderTest.kt
index cd5116c0..eb373d2f 100644
--- a/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/structures/MapDecoderTest.kt
+++ b/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/structures/MapDecoderTest.kt
@@ -1,9 +1,11 @@
 package com.akuleshov7.ktoml.decoders.structures
 
 import com.akuleshov7.ktoml.Toml
+import com.akuleshov7.ktoml.TomlInputConfig
 import com.akuleshov7.ktoml.exceptions.IllegalTypeException
 import com.akuleshov7.ktoml.exceptions.MissingRequiredPropertyException
 import com.akuleshov7.ktoml.exceptions.TomlDecodingException
+import com.akuleshov7.ktoml.parsers.TomlParser
 import kotlinx.serialization.SerialName
 import kotlinx.serialization.Serializable
 import kotlinx.serialization.decodeFromString
@@ -149,6 +151,64 @@ class MapDecoderTest {
         )
     }
 
+    @Test
+    fun testMapWithArray() {
+        @Serializable
+        data class VersionCatalog(
+            val bundles: Map<String, List<String>> = emptyMap(),
+        )
+
+        val toml = """
+            [bundles]
+            koin = [
+                "koin-core",
+                "koin-compose",
+                "koin-compose-viewmodel"
+            ]
+
+            ktor-common = [
+                "ktor-client-core",
+                "ktor-client-content-negotiation",
+                "ktor-serialization-kotlinx-json",
+                "ktor-client-auth",
+                "ktor-client-logging"
+            ]
+
+            ktor-commond = [
+                "ktor-client-core",
+                "ktor-client-content-negotiation",
+                "ktor-serialization-kotlinx-json",
+                "ktor-client-auth",
+                "ktor-client-loggqing"
+            ]
+        """.trimIndent()
+
+        val expected = VersionCatalog(
+            mapOf(
+                "koin" to listOf("koin-core", "koin-compose", "koin-compose-viewmodel"),
+                "ktor-common" to listOf(
+                    "ktor-client-core",
+                    "ktor-client-content-negotiation",
+                    "ktor-serialization-kotlinx-json",
+                    "ktor-client-auth",
+                    "ktor-client-logging"
+                ),
+                "ktor-commond" to listOf(
+                    "ktor-client-core",
+                    "ktor-client-content-negotiation",
+                    "ktor-serialization-kotlinx-json",
+                    "ktor-client-auth",
+                    "ktor-client-loggqing"
+                )
+            )
+        )
+        val result = Toml.decodeFromString<VersionCatalog>(toml)
+        assertEquals(
+            expected,
+            result
+        )
+    }
+
     @Test
     fun decodeMapOfObjects() {
         @Serializable