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. 😉
Gradle Kotlin (build.gradle.kts)
repositories {
mavenCentral()
}
dependencies {
implementation("net.peanuuutz.tomlkt:tomlkt:0.4.0")
}
Gradle Groovy (build.gradle)
repositories {
mavenCentral()
}
dependencies {
implementation "net.peanuuutz.tomlkt:tomlkt:0.4.0"
}
Maven (.pom)
<dependency>
<groupId>net.peanuuutz.tomlkt</groupId>
<artifactId>tomlkt-jvm</artifactId>
<version>0.4.0</version>
</dependency>
Note: If your project is Kotlin Multiplatform, you can simply add this into commonMain dependencies.
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.
}
TOML Data Type | Encoding | Decoding |
---|---|---|
Comment | ✔️ | ✔️ |
Key | ✔️ | ✔️ |
String | ✔️ | ✔️ |
Integer | ✔️ | ✔️ |
Float | ✔️ | ✔️ |
Boolean | ✔️ | ✔️ |
Date Time | ✔️ | ✔️ |
Array | ✔️ | ✔️ |
Table | ✔️ | ✔️ |
Inline Table | ✔️ | ✔️ |
Array of Tables | ✔️ | ✔️ |
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
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.
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.
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.
For other information, view API docs.