Config for Kotlin.
Config4k is a lightweight Typesafe Config wrapper for Kotlin and inspired by ficus, providing simple extension functions Config.extract<T> and Any.toConfig to convert between Config and Kotlin Objects.
import com.typesafe.config.ConfigFactory
import io.github.config4k.*
data class Person(val name: String, val age: Int)
data class Family(val list: List<Person>)
// typesafe config supports not only HOCON but also JSON
// HOCON(Human-Optimized Config Object Notation) is the JSON superset
val config = ConfigFactory.parseString("""
| // HOCON style
|family {
| list = [{
| name = "foo"
| age = 20
| }, {
| name = "bar"
| age = 25
| }]
|}""".trimMargin())
// typesafe config + config4k
config.extract<Family>("family")Gradle:
repositories {
jcenter()
}
dependencies {
compile 'io.github.config4k:config4k:xxx' // See the `Download` badge
}Config.extract<T> converts Config to T.
Config4k has no option to use different names between code and config file.
data class Person(val name: String, val age: Int)
val config = ConfigFactory.parseString("""
|key {
| name = "foo"
| age = 20
|}""".trimMargin())
val person: Person = config.extract<Person>("key")
person.name == "foo" // true
person.age == 20 // trueFor more details, please see TestArbitraryType.kt
Using extract<T?> is the better way than Config.hasPath().
extract<T?> returns T when the path exists and null when it does not exist.
val config = ConfigFactory.parseString("""key = 10""")
val key = config.extract<Int?>("key")
val foo = config.extract<Int?>("foo")
key == 10 // true
foo == null // trueTest Class: TestNullable.kt
Config4k also supports Enum. Enum is converted to String of its name in the config file.
enum class Size {
SMALL,
MEDIUM,
LARGE
}
val config = ConfigFactory.parseString("""key = SMALL""")
val small = config.extract<Size>("key")
small == Size.SMALL // trueTest Class: TestEnum.kt
Any.toConfig converts the receiver object to Config.
You can use ConfigValue.render() to serialize Config. Config4k helps getting Config of the class you want to serialize.
data class Person(val name: String, val age: Int)
val person = Person("foo", 20).toConfig("person")
println(person.root().render()) Output:
{
# hardcoded value
"person" : {
# hardcoded value
"age" : 20,
# hardcoded value
"name" : "foo"
}
}
Test Class: TestToConfigForArbitraryType.kt
Typesafe Config's class ConfigRenderOptions is the argument of ConfigValue.render.
// If setJson(false) is called, ConfigValue.render returns HOCON
val options = ConfigRenderOptions.defaults().setJson(false)
println(person.root().render(option))Output:
# hardcoded value
person {
# hardcoded value
age=20
# hardcoded value
name=foo
}
// setOriginComments(false) removes comments
val options = ConfigRenderOptions.defaults()
.setJson(false)
.setOriginComments(false)
println(person.root().render(option))Output:
person {
age=20
name=foo
}
extract and toConfig support these types.
- Primitive types
BooleanIntLongDouble
Stringjava.time.Duration- Collections
ListSetMap<String, T>Array<T>(You can useArray<Int>, but can't useArray<Array<Int>>)
- Nullable
T? - Typesafe Config classes(Calling
toConfigis meaningless)com.typesafe.config.Configcom.typesafe.config.ConfigValue
- Enum
- Data classes
PRs accepted.