Code Monkey home page Code Monkey logo

4koma's Introduction

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, serialization support, 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, and do it well. If what you need is no-nonsense TOML processing for your Kotlin project, 4koma might be just what you need. 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:1.0.1")
}

2. Obtain a TOML file

[settings]
maxLoginRetries = 3

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

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

3. Write some code

A minimal example

import cc.ekblad.toml.decode
import cc.ekblad.toml.tomlMapper
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() {
    // Create a TOML mapper without any custom configuration
    val mapper = tomlMapper { }

    // Read our config from file
    val tomlFile = Path.of("test.toml")
    val config = mapper.decode<Config>(tomlFile)
    println(config)
}

Default values

import cc.ekblad.toml.decodeWithDefaults
import cc.ekblad.toml.tomlMapper
import java.nio.file.Path

// We extend our config with extra fields (e.g. isAdmin, realmName and useTLS)
// which are not configured in our example TOML document.
data class Config(
    val settings: Settings,
    val user: List<User>
) {
    data class User(val name: String, val password: String, val isAdmin: Boolean)
    data class Settings(val maxLoginRetries: Int, val realmName: String, val useTLS: Boolean)
}

// Then, we define a default configuration, from which we will fill in any missing values when we read the config.
val defaultConfig = Config(
    settings = Config.Settings(
        maxLoginRetries = 5,
        realmName = "Example Realm",
        useTLS = true
    ),
    user = emptyList()
)

// We also define a default value for our user type, as we extended it with an extra field.
val defaultUser = Config.User(
    name = "default name",
    password = "default password",
    isAdmin = false
)

fun main() {
    // Create a TOML mapper with default fields configured for our Config.User type.
    val mapper = tomlMapper {
        default(defaultUser)
    }

    // Read our config from file, replacing any missing values with the defaults from defaultConfig and defaultUser.
    val tomlFile = Path.of("test.toml")
    val config = mapper.decodeWithDefaults<Config>(defaultConfig, tomlFile)
    println(config)
}

Mapping between TOML and Kotlin field names

import cc.ekblad.toml.decode
import cc.ekblad.toml.tomlMapper
import java.nio.file.Path

data class Config(
    val settings: Settings,
    val users: List<User>
) {
    data class User(val userName: String, val password: String)
    data class Settings(val retriesAfterWhichToDisableLogin: Int)
}

fun main() {
    // Set up a mapper which maps "user", "name", etc. fields found in the TOML file onto fields "users", "userName",
    // etc. in their respective Kotlin data types
    val mapper = tomlMapper {
        mapping<Config>("user" to "users")
        mapping<Config.User>(
            "name" to "userName",
            "password" to "userSecret"
        )
        mapping<Config.Settings>(
            "maxLoginRetries" to "retriesAfterWhichToDisableLogin"
        )
    }

    // Read our config from file, using our custom field name mappings
    val tomlFile = Path.of("test.toml")
    val config = mapper.decode<Config>(tomlFile)
    println(config)
}

Custom decoders

import cc.ekblad.toml.decode
import cc.ekblad.toml.model.TomlValue
import cc.ekblad.toml.tomlMapper
import java.nio.file.Path

fun main() {
    // Set up a mapper which replaces any string appearing in the list of bad words with a number of asterisks
    val listOfBadWords = listOf("poop", "darn", "blockchain")
    val mapper = tomlMapper {
        decoder { it: TomlValue.String ->
            if (it.value in listOfBadWords) {
                // We don't allow any swearing in our strings!
                it.value.map { '*' }.joinToString("")
            } else {
                it.value
            }
        }
    }

    // Read an arbitrary TOML document from file, using our custom string decoder
    val tomlFile = Path.of("test.toml")
    val config = mapper.decode<Map<String, Any>>(tomlFile)
    println(config)
}

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 this 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.

4koma's People

Contributors

valderman avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.