diff --git a/README.md b/README.md index 2a595912..eafcbcbe 100644 --- a/README.md +++ b/README.md @@ -81,12 +81,12 @@ To import `ktoml` library you need to add following dependencies to your code: com.akuleshov7 ktoml-core - 0.2.10 + 0.2.11 com.akuleshov7 ktoml-file - 0.2.10 + 0.2.11 ``` @@ -95,8 +95,8 @@ To import `ktoml` library you need to add following dependencies to your code: Gradle Groovy ```groovy -implementation 'com.akuleshov7:ktoml-core:0.2.10' -implementation 'com.akuleshov7:ktoml-file:0.2.10' +implementation 'com.akuleshov7:ktoml-core:0.2.11' +implementation 'com.akuleshov7:ktoml-file:0.2.11' ``` @@ -104,8 +104,8 @@ implementation 'com.akuleshov7:ktoml-file:0.2.10' Gradle Kotlin ```kotlin -implementation("com.akuleshov7:ktoml-core:0.2.10") -implementation("com.akuleshov7:ktoml-file:0.2.10") +implementation("com.akuleshov7:ktoml-core:0.2.11") +implementation("com.akuleshov7:ktoml-file:0.2.11") ``` diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/StringUtils.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/StringUtils.kt index 2be4b154..b735f098 100644 --- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/StringUtils.kt +++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/StringUtils.kt @@ -6,6 +6,15 @@ package com.akuleshov7.ktoml.parsers import com.akuleshov7.ktoml.exceptions.ParseException +/** + * method to find the beginning of the comments in TOML string + * + * @param startSearchFrom the index after that the search will be done + * @return the index of the first hash symbol or the index of the end of the string + */ +internal fun String.findBeginningOfTheComment(startSearchFrom: Int) = + (startSearchFrom until this.length).filter { this[it] == '#' }.minOrNull() ?: this.length + /** * Splitting dot-separated string to the list of tokens: * a.b.c -> [a, b, c]; a."b.c".d -> [a, "b.c", d]; diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/TomlParser.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/TomlParser.kt index 2867a206..c7c7bf4a 100644 --- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/TomlParser.kt +++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/parsers/TomlParser.kt @@ -95,7 +95,6 @@ public value class TomlParser(private val config: TomlConfig) { } } } - tomlFileHead.prettyPrint() return tomlFileHead } @@ -119,14 +118,11 @@ public value class TomlParser(private val config: TomlConfig) { return this } - private fun String.isArrayOfTables(): Boolean { - val trimmed = this.trim() - return trimmed.startsWith("[[") && trimmed.endsWith("]]") - } + private fun String.isArrayOfTables(): Boolean = this.trim().startsWith("[[") private fun String.isTableNode(): Boolean { val trimmed = this.trim() - return trimmed.startsWith("[") && trimmed.endsWith("]") + return trimmed.startsWith("[") } private fun String.isComment() = this.trim().startsWith("#") diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlArrayOfTables.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlArrayOfTables.kt index a0aaaf60..9768ce8a 100644 --- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlArrayOfTables.kt +++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlArrayOfTables.kt @@ -6,12 +6,15 @@ package com.akuleshov7.ktoml.tree import com.akuleshov7.ktoml.TomlConfig import com.akuleshov7.ktoml.exceptions.ParseException +import com.akuleshov7.ktoml.parsers.findBeginningOfTheComment import com.akuleshov7.ktoml.parsers.splitKeyToTokens import com.akuleshov7.ktoml.parsers.trimDoubleBrackets import com.akuleshov7.ktoml.parsers.trimQuotes /** - * @property isSynthetic + * Class representing array of tables + * + * @throws ParseException if the content is wrong */ // FixMe: this class is mostly identical to the TomlTable - we should unify them together public class TomlArrayOfTables( @@ -37,8 +40,18 @@ public class TomlArrayOfTables( public override lateinit var fullTableName: String init { + val lastIndexOfBrace = content.lastIndexOf("]]") + if (lastIndexOfBrace == -1) { + throw ParseException("Invalid Array of Tables provided: $content." + + " It has missing closing brackets: ']]'", lineNo) + } + + // finding the index of the beginning of the comment (if any) + val firstHash = content.findBeginningOfTheComment(lastIndexOfBrace) + // getting the content inside brackets ([a.b] -> a.b) - val sectionFromContent = content.trim().trimDoubleBrackets().trim() + val sectionFromContent = content.substring(0, firstHash).trim().trimDoubleBrackets() + .trim() if (sectionFromContent.isBlank()) { throw ParseException("Incorrect blank name for array of tables: $content", lineNo) diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlInlineTable.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlInlineTable.kt index 46ad815d..7edd133e 100644 --- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlInlineTable.kt +++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlInlineTable.kt @@ -73,8 +73,6 @@ public class TomlInlineTable( } } - - tomlTable.prettyPrint() return tomlTable } } diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlKeyValue.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlKeyValue.kt index 380b8632..43e771c8 100644 --- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlKeyValue.kt +++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlKeyValue.kt @@ -2,6 +2,7 @@ package com.akuleshov7.ktoml.tree import com.akuleshov7.ktoml.TomlConfig import com.akuleshov7.ktoml.exceptions.ParseException +import com.akuleshov7.ktoml.parsers.findBeginningOfTheComment /** * Interface that contains all common methods that are used in KeyValue nodes @@ -69,7 +70,7 @@ public fun String.splitKeyValue(lineNo: Int, config: TomlConfig = TomlConfig()): // finding the index of a commented part of the string // search starts goes from the closingQuoteIndex to the end of the string - val firstHash = (closingQuoteIndex until this.length).filter { this[it] == '#' }.minOrNull() ?: this.length + val firstHash = this.findBeginningOfTheComment(closingQuoteIndex) // searching for an equals sign that should be placed main part of the string (not in the comment) val firstEqualsSign = this.substring(0, firstHash).indexOfFirst { it == '=' } diff --git a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlTablePrimitive.kt b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlTablePrimitive.kt index 29458ff1..ef2a3943 100644 --- a/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlTablePrimitive.kt +++ b/ktoml-core/src/commonMain/kotlin/com/akuleshov7/ktoml/tree/TomlTablePrimitive.kt @@ -6,6 +6,7 @@ package com.akuleshov7.ktoml.tree import com.akuleshov7.ktoml.TomlConfig import com.akuleshov7.ktoml.exceptions.ParseException +import com.akuleshov7.ktoml.parsers.findBeginningOfTheComment import com.akuleshov7.ktoml.parsers.splitKeyToTokens import com.akuleshov7.ktoml.parsers.trimBrackets import com.akuleshov7.ktoml.parsers.trimQuotes @@ -39,8 +40,18 @@ public class TomlTablePrimitive( public override lateinit var fullTableName: String init { + val lastIndexOfBrace = content.lastIndexOf("]") + if (lastIndexOfBrace == -1) { + throw ParseException("Invalid Tables provided: $content." + + " It has missing closing bracket: ']'", lineNo) + } + + // finding the index of the beginning of the comment (if any) + val firstHash = content.findBeginningOfTheComment(lastIndexOfBrace) + // getting the content inside brackets ([a.b] -> a.b) - val sectionFromContent = content.trim().trimBrackets().trim() + val sectionFromContent = content.substring(0, firstHash).trim().trimBrackets() + .trim() if (sectionFromContent.isBlank()) { throw ParseException("Incorrect blank table name: $content", lineNo) diff --git a/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/ReadMeExampleTest.kt b/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/ReadMeExampleTest.kt index 11a55c9f..f91e010a 100644 --- a/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/ReadMeExampleTest.kt +++ b/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/decoders/ReadMeExampleTest.kt @@ -55,27 +55,27 @@ class ReadMeExampleTest { fun readmeExampleTest() { val test = """ - |someBooleanProperty = true - |# inline tables in gradle 'libs.versions.toml' notation - |gradle-libs-like-property = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } - | - |[table1] - |property1 = null - |property2 = 6 - | - |[table2] - |someNumber = 5 - | [table2."akuleshov7.com"] - | name = 'this is a "literal" string' - | # empty lists are also supported - | configurationList = ["a", "b", "c", null] - | - |# such redeclaration of table2 - |# is prohibited in toml specification; - |# but ktoml is allowing it in non-strict mode: - |[table2] - |otherNumber = 5.56 - | + someBooleanProperty = true + # inline tables in gradle 'libs.versions.toml' notation + gradle-libs-like-property = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" } + + [table1] + property1 = null # null is prohibited by the TOML spec, + property2 = 6 + + [table2] + someNumber = 5 + [table2."akuleshov7.com"] + name = 'this is a "literal" string' + # empty lists are also supported + configurationList = ["a", "b", "c", null] + + # such redeclaration of table2 + # is prohibited in toml specification; + # but ktoml is allowing it in non-strict mode: + [table2] + otherNumber = 5.56 + """.trimMargin() val decoded = Toml.decodeFromString(test) diff --git a/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/parsers/CommentsParsing.kt b/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/parsers/CommentsParsing.kt new file mode 100644 index 00000000..d9d4cc11 --- /dev/null +++ b/ktoml-core/src/commonTest/kotlin/com/akuleshov7/ktoml/parsers/CommentsParsing.kt @@ -0,0 +1,20 @@ +package com.akuleshov7.ktoml.parsers + +import com.akuleshov7.ktoml.Toml +import kotlin.test.Test + +class CommentsParsing { + @Test + fun commentsParsing() { + val string = """ + # comment 1 + [a] # comment 2 + # comment 3 + test = 1 # comment 4 + [[a.b]] # comment 5 + test = 1 + """.trimIndent() + val parsedToml = Toml.tomlParser.parseString(string) + parsedToml.prettyPrint() + } +}