tomlkt
Powerful and easy to use kotlinx.serialization plugin for TOML 1.0.0 compliance encoding and decoding.
If you find any problem along usage, please raise an issue. :wink:
Setup
Gradle Kotlin (build.gradle.kts)
kotlin
repositories {
mavenCentral()
}
dependencies {
implementation("net.peanuuutz.tomlkt:tomlkt:0.5.0")
}
Gradle Groovy (build.gradle)
groovy
repositories {
mavenCentral()
}
dependencies {
implementation "net.peanuuutz.tomlkt:tomlkt:0.5.0"
}
Maven (.pom)
xml
<dependency>
<groupId>net.peanuuutz.tomlkt</groupId>
<artifactId>tomlkt-jvm</artifactId>
<version>0.5.0</version>
</dependency>
Note: If your project is Kotlin Multiplatform, you can simply add this into commonMain dependencies.
Quick Start
Write some config:
name = "Peanuuutz"
[account]
username = "Peanuuutz"
password = "123456"
Write some code:
@Serializable
data class User(
val name: String,
val account: Account?
)
@Serializable
data class Account(
val username: String,
val password: String
)
fun main() {
// Here we use JVM.
val tomlString = Paths.get("...").readText()
// Either is OK, but to explicitly pass a serializer is faster.
val user = Toml.decodeFromString(User.serializer(), tomlString)
val user = Toml.decodeFromString<User>(tomlString)
// That's it!
// By the way if you need some configuration.
val toml = Toml {
ignoreUnknownKeys = true
}
// Use toml to apply the change.
// Encoding.
val anotherUser = User("Anonymous", null)
// Again, better to explicitly pass a serializer.
val config = Toml.encodeToString(User.serializer(), anotherUser)
Paths.get("...").writeText(config)
// Done.
}
Supported TOML Features
| TOML Data Type | Encoding | Decoding |
|---|---|---|
| Comment | :heavy_check_mark: | :heavy_check_mark: |
| Key | :heavy_check_mark: | :heavy_check_mark: |
| String | :heavy_check_mark: | :heavy_check_mark: |
| Integer | :heavy_check_mark: | :heavy_check_mark: |
| Float | :heavy_check_mark: | :heavy_check_mark: |
| Boolean | :heavy_check_mark: | :heavy_check_mark: |
| Date Time | :heavy_check_mark: | :heavy_check_mark: |
| Array | :heavy_check_mark: | :heavy_check_mark: |
| Table | :heavy_check_mark: | :heavy_check_mark: |
| Inline Table | :heavy_check_mark: | :heavy_check_mark: |
| Array of Tables | :heavy_check_mark: | :heavy_check_mark: |
Comment
Implemented as an annotation @TomlComment on properties:
class IntData(
@TomlComment("""
An integer,
but is decoded into Long originally.
""")
val int: Int
)
IntData(10086)
The code above will be encoded into:
# An integer,
# but is decoded into Long originally.
int = 10086
String
Basic strings are encoded as "<content>". For multilines and literals, put an annotation as
below:
class MultilineStringData(
@TomlMultilineString
val multilineString: String
)
MultilineStringData("""
Do, a deer, a female deer.
Re, a drop of golden sun.
""".trimIndent())
class LiteralStringData(
@TomlLiteralString
val literalString: String
)
LiteralStringData("C:\\Users\\<User>\\.m2\\repositories")
The code above will be encoded into:
multilineString = """
Do, a deer, a female deer.
Re, a drop of golden sun."""
literalString = 'C:\Users\<User>\.m2\repositories'
You can use both annotations to get multiline literal string.
Date Time
TOML supports several date time formats, so does tomlkt. tomlkt declares TomlLocalDateTime,
TomlOffsetDateTime, TomlLocalDate, TomlLocalTime as expect types with builtin support for
serialization (@Serializable).
The mapping of these expect types are as follows:
| tomlkt | java.time | kotlinx.datetime |
|---|---|---|
| TomlLocalDateTime | LocalDateTime | LocalDateTime |
| TomlOffsetDateTime | OffsetDateTime | Instant |
| TomlLocalDate | LocalDate | LocalDate |
| TomlLocalTime | LocalTime | LocalTime |
TomlLiteral is the default intermediate representation of a date time. For conversion,
simply use TomlLiteral(TomlLocalDateTime) to create a TomlLiteral from a TomlLocalDateTime
(true for other types), and TomlLiteral.toLocalDateTime() for the other way.
If you would like to provide a custom serializer, use NativeLocalDateTime and the like as raw
types.
TomlElement
The working process of tomlkt:
- Encoding: Model → (TomlElementEncoder) → TomlElement → (TomlElementEmitter) → File.
- Decoding: File → (TomlElementParser) → TomlElement → (TomlElementDecoder) → Model.
As shown, if you already have a TOML file, you can have no model class, but still gain access
to every entry with the help of TomlElement. Simply parse the file with
Toml.parseToTomlTable, then access entries via various TomlTable extensions. Also, if you
are a framework author, you would also need the power of dynamic construction. For example, you
can construct a TomlTable like this:
val table = buildTomlTable {
literal("title", "TOML Example")
table("database") {
literal("enabled", true)
array("ports", TomlInline.Instance) {
literal(8000)
}
table("temperature") {
val commentForCpu = """
The max temperature for the core.
DO NOT SET OVER 100.0!
""".trimIndent()
literal("cpu", 79.5, TomlComment(commentForCpu))
}
}
array("servers", TomlComment("Available servers.")) {
table {
literal("ip", "10.0.0.1")
literal("role", "main")
}
table {
literal("ip", "10.0.0.2")
}
}
}
The code above will be encoded into:
title = "TOML Example"
[database]
enabled = true
ports = [ 8000 ]
[database.temperature]
# The max temperature for the core.
# DO NOT SET OVER 100.0!
cpu = 79.5
# Available servers.
[[servers]]
ip = "10.0.0.1"
role = "main"
[[servers]]
ip = "10.0.0.2"
Note: All the metadata coming from annotations is ignored in the parser, meaning that despite you could parse a file into an element, you cannot emit it back to file fully as is.
Others
For other information, view API docs.
