Config4k

repository·main·Indexed 43 days ago

https://github.com/config4k/config4k

A lightweight Kotlin wrapper for the Typesafe Config library that simplifies mapping configuration files to Kotlin data classes and vice versa. It provides extension functions like `Config.extract<T>()` for deserialization and `Any.toConfig()` for serialization, as well as support for Kotlin delegated properties and a wide range of supported types including primitives, collections, and enums.

Tokens
2.6K
Snippets
13
Records
18
Agent score
55%

What's inside Config4k

  1. Convert between Config and Kotlin Objects

    main

    Config4k provides extension functions to bridge the gap between Typesafe Config objects and Kotlin data classes/objects.

    Key functions:

    • Config.extract<T>(): Converts a Typesafe Config object into a Kotlin type T.
    • Any.toConfig(): Converts a Kotlin object into a Typesafe Config object.
  2. Install Config4k via Gradle

    main

    To use Config4k in your Kotlin project, add mavenCentral() to your repositories block and include the config4k dependency in your dependencies block. Replace xxx with the latest version available.

    repositories {
        mavenCentral()
    }
    
    dependencies {
        compile 'io.github.config4k:config4k:xxx' // See the `Download` badge
    }
  3. Serialize objects to Config using Any.toConfig

    main

    You can convert any Kotlin object into a Typesafe Config object using the Any.toConfig extension function. Once converted to a Config object, you can use the standard Typesafe Config ConfigValue#render method to serialize the configuration into a string format (such as HOCON or JSON).

    // Assuming an object 'person' exists
    val config = person.toConfig()
    val renderedString = config.render()
  4. Handle optional configuration values using extract<T?>

    main

    Instead of manually checking for a configuration path using Config.hasPath(), you should use the nullable type parameter extract<T?>().

    When you call extract<T?>(), the function returns the deserialized value of type T if the path exists, or null if the path does not exist in the configuration. This provides a more idiomatic and concise way to handle optional configuration settings in Kotlin.

    // Example pattern (logic extracted from DocExamples.kt)
    val value: MyType? = config.extract<MyType?>("path.to.optional.config")
    // value is null if path does not exist, otherwise it is MyType
  5. Deserialize configuration into Kotlin data classes

    main

    Config4k allows you to deserialize HOCON/JSON configuration files directly into Kotlin data classes. Note that Config4k requires the property names in your configuration file to match the parameter names in your data class exactly; there is no built-in option to map different names between the code and the config file.

    // The actual implementation is located in src/test/kotlin/io/github/config4k/DocExamples.kt
    // Example pattern:
    
    data class MyConfig(val name: String, val port: Int)
    
    val config = ConfigFactory.parseString("name = 'app', port = 8080").extract<MyConfig>()
  6. Use Kotlin Delegated Properties for configuration

    main

    The simplest way to integrate configuration into your Kotlin classes is by using Kotlin Delegated Properties. This allows you to map configuration keys directly to class properties. When the property is accessed, config4k automatically retrieves and casts the value from the underlying configuration source.

    To use this pattern, you typically use the config.property<T>(key) delegate (or similar extension functions provided by the library) within your class definition.

    // Example pattern based on DocExamples.kt
    class MyConfig(config: Config) {
        val myProperty: String by config.property()
        val myInt: Int by config.property()
    }
  7. Use default values during deserialization with extract<T, T?>

    main

    When using Config.extract<T>, the process will fail if the requested path is missing in the configuration. To handle missing paths gracefully, use the extract<T, T?> method. This method returns the value of type T if the path exists, or the provided default value if the path is missing.

    Note: The second type parameter in the generic signature extract<T, T?> allows the function to return a nullable type or a specific fallback type when the configuration key is absent.

    // Example pattern for using default values
    // The actual implementation details are in the DocExamples.kt source
    val value = config.extract<String, String>("path.to.key", "default_value")
  8. Install Config4k

    main

    Config4k is a lightweight wrapper for Typesafe Config in Kotlin. You can find the latest stable artifacts on Maven Central under the group ID io.github.config4k and artifact ID config4k.

    <!-- Example Maven dependency (verify exact version on Maven Central) -->
    <dependency>
        <groupId>io.github.config4k</groupId>
        <artifactId>config4k</artifactId>
        <version>0.7.0</version>
    </dependency>
  9. Customize HOCON rendering with ConfigRenderOptions

    main

    When serializing data back to HOCON format using ConfigValue#render, you can pass an instance of Typesafe Config's ConfigRenderOptions to control the output format. This allows you to include or exclude comments and other formatting details in the resulting configuration string.

    To include hardcoded comments in the output, use the default or specifically configured ConfigRenderOptions. To produce a clean output without comments, use ConfigRenderOptions.defaults().withoutComments().

    // Example of rendering with comments (default behavior)
    val hoconWithComments = configValue.render(ConfigRenderOptions.defaults())
    
    // Example of rendering without comments
    val hoconWithoutComments = configValue.render(ConfigRenderOptions.defaults().withoutComments())
  10. Deserialize Enums from configuration

    main

    Config4k supports deserializing Kotlin Enum types. When mapping a configuration value to an Enum, the value in the configuration file must be a String that matches the exact name of one of the Enum constants.

    // Example representation of how Enums are handled
    enum class Color { RED, GREEN, BLUE }
    
    // In your config file (HOCON/JSON/etc):
    // color = "RED"
    
    // Deserialization will map the string "RED" to Color.RED