4koma

Docs
Release
Build Status
Coverage
License

A small, stand-alone, easy to use TOML parser library for Kotlin.

4koma supports an array of convenient features, such as full TOML 1.0 compliance,
type-safe decoding of configurations into arbitrary data classes using Kotlin generics,
and easy access to individual properties for when you don’t need the entire document.

4koma follows the UNIX philosophy, in that it tries to do one thing (i.e. TOML processing for Kotlin projects),
and do it well.
If you need support for multiple configuration formats, or are using a JVM language other than Kotlin,
some of the projects listed in the Alternatives section might serve you better.

Usage

Getting started with 4koma is super easy.

1. Add a dependency on 4koma

For build.gradle.kts:

repositories {
    maven {
        url = uri("https://jitpack.io")
    }
}

dependencies {
    implementation("cc.ekblad:4koma:0.3.0")
}

2. Obtain a TOML file

[settings]
maxLoginTries = 3

[[user]]
name = "Alice"
password = "password123"

[[user]]
name = "Bob"
password = "correct horse battery staple"

3. Write some code

import cc.ekblad.toml.TomlDecoder
import cc.ekblad.toml.TomlValue
import cc.ekblad.toml.decode
import cc.ekblad.toml.withMapping
import cc.ekblad.toml.get
import java.nio.file.Path

data class Config(
    val settings: Settings,
    val user: List<User>
) {
    data class User(val name: String, val password: String)
    data class Settings(val maxLoginRetries: Int)
}

fun main() {
    // Parse a TOML document from a string, stream, or file
    val tomlDocument = TomlValue.from(Path.of("test.toml"))

    // Decode it to your config type
    val config = tomlDocument.decode<Config>()

    // If you're lazy, just decode it to a map
    val mapConfig = tomlDocument.decode<Map<String, Any>>()

    // ...or access properties directly
    val maxLoginTries = tomlDocument["settings", "maxLoginTries"]

    // ...or just grab a part of the document and decode it to some convenient data class
    val settings = tomlDocument.get<Config.Settings>("settings")
    val users = tomlDocument.get<List<User>>("user")

    // You can also access properties on objects inside lists
    val userNames = tomlDocument["user", "name"] // <- returns listOf("Alice", "Bob")

    // Need to remap some names between your config file and your model types?
    data class RemappedConfig(val users: List<User>) {
        data class User(val userName: String, val userSecret: String)
    }
    val remappingDecoder = TomlDecoder.default
        .withMapping<RemappedConfig>("user" to "users")
        .withMapping<RemappedConfig.User>("name" to "userName", "password" to "userSecret")
    val remappedConfig = tomlDocument.decode<RemappedConfig>(remappingDecoder)

    // You can also use entirely custom decoder functions
    val censoringDecoder = TomlDecoder.default.with { it: TomlValue.String -> 
        if (it.value in listOfBadWords) {
            // We don't allow any swearing in our strings!
            it.value.map { '*' }.joinToString("")
        } else {
            it.value
        }
    }
    val censoredConfig = tomlDocument.decode<Config>(censoringDecoder)
}

For more detailed information, see the API documentation.

Alternatives

Why should you use 4koma? Maybe you shouldn’t! When it comes to TOML libraries there are several to choose from.
This table compares 4koma with a number of alternatives that (a) can parse TOML, (b) can be reasonably easily used in
a Kotlin/JVM project, and (c) have seen at least one new commit in the last four years.

If you’d like your library to be on your list, or it’s already there and you believe it’s being misrepresented,
please open a pull request to rectify the situation.

Feature 4koma KToml konf konfy toml4j tomlj jtoml Night Config Jackson
TOML 1.0 compliant
TOML 0.4 compliant
Inline tables
Table arrays
Date/time literals
Easy property access¹
Decodes to Kotlin types
…without extra boilerplate²
…without modification to type
Type-safe generic decoding³
Kotlin multiplatform
Serialization
Online API docs
Small and lean⁴
Everything but the kitchen sink⁵

(¹) Individual properties can be accessed by means of parsedConfig.get("foo.bar") or similar,
without requiring the entire document to be decoded into some model type.

(²) The library does not require annotations or other modifications to existing code in order to support decoding
to complex model types.

(³) The library does not rely on type-erased JVM generics for decoding to complex model types.

(⁴) The library focuses on reading/writing/processing TOML and does not contain any “unnecessary” features
unrelated to that scope.

(⁵) The library aims to provide a comprehensive configuration platform, with support for multiple configuration file
formats and all sorts of associated bells and whistles.

GitHub

View Github