Skip to content

Commit

Permalink
fix: correctly implement MergedSource
Browse files Browse the repository at this point in the history
  • Loading branch information
uchuhimo committed Oct 11, 2020
1 parent a137791 commit d5ed231
Show file tree
Hide file tree
Showing 17 changed files with 166 additions and 81 deletions.
57 changes: 29 additions & 28 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ compile(group = "com.github.uchuhimo.konf", name = "konf", version = "master-SNA
```kotlin
object ServerSpec : ConfigSpec() {
val host by optional("0.0.0.0")
val port by required<Int>()
val tcpPort by required<Int>()
}
```

Expand Down Expand Up @@ -201,34 +201,34 @@ compile(group = "com.github.uchuhimo.konf", name = "konf", version = "master-SNA
```yaml
server:
host: 0.0.0.0
port: 8080
tcp_port: 8080
```
- in `server.json`:
```json
{
"server": {
"host": "0.0.0.0",
"port": 8080
"tcp_port": 8080
}
}
```
- in system environment:
```bash
SERVER_HOST=0.0.0.0
SERVER_PORT=8080
SERVER_TCPPORT=8080
```
- in command line for system properties:
```bash
-Dserver.host=0.0.0.0 -Dserver.port=8080
-Dserver.host=0.0.0.0 -Dserver.tcp_port=8080
```

4. Retrieve values from config with type-safe APIs:
```kotlin
data class Server(val host: String, val port: Int) {
data class Server(val host: String, val tcpPort: Int) {
fun start() {}
}

val server = Server(config[ServerSpec.host], config[ServerSpec.port])
val server = Server(config[ServerSpec.host], config[ServerSpec.tcpPort])
server.start()
```

Expand Down Expand Up @@ -260,7 +260,7 @@ If the config spec is binding with single class, you can declare config spec as
class Server {
companion object : ConfigSpec("server") {
val host by optional("0.0.0.0")
val port by required<Int>()
val tcpPort by required<Int>()
}
}
```
Expand Down Expand Up @@ -299,11 +299,11 @@ There are three kinds of item:

- Required item. Required item doesn't have default value, thus must be set with value before retrieved in config. Define a required item with description:
```kotlin
val port by required<Int>(description = "port of server")
val tcpPort by required<Int>(description = "port of server")
```
Or omit the description:
```kotlin
val port by required<Int>()
val tcpPort by required<Int>()
```
- Optional item. Optional item has default value, thus can be safely retrieved before setting. Define an optional item:
```kotlin
Expand All @@ -312,7 +312,7 @@ There are three kinds of item:
Description can be omitted.
- Lazy item. Lazy item also has default value, however, the default value is not a constant, it is evaluated from thunk every time when retrieved. Define a lazy item:
```kotlin
val nextPort by lazy { config -> config[port] + 1 }
val nextPort by lazy { config -> config[tcpPort] + 1 }
```

You can also define config spec in Java, with a more verbose API (compared to Kotlin version in "quick start"):
Expand All @@ -324,7 +324,7 @@ public class ServerSpec {
public static final OptionalItem<String> host =
new OptionalItem<String>(spec, "host", "0.0.0.0") {};

public static final RequiredItem<Integer> port = new RequiredItem<Integer>(spec, "port") {};
public static final RequiredItem<Integer> tcpPort = new RequiredItem<Integer>(spec, "tcpPort") {};
}
```

Expand Down Expand Up @@ -418,73 +418,73 @@ config.validateRequired()
Associate item with value (type-safe API):

```kotlin
config[Server.port] = 80
config[Server.tcpPort] = 80
```

Find item with specified name, and associate it with value (unsafe API):

```kotlin
config["server.port"] = 80
config["server.tcpPort"] = 80
```

Discard associated value of item:

```kotlin
config.unset(Server.port)
config.unset(Server.tcpPort)
```

Discard associated value of item with specified name:

```kotlin
config.unset("server.port")
config.unset("server.tcpPort")
```

Associate item with lazy thunk (type-safe API):

```kotlin
config.lazySet(Server.port) { it[basePort] + 1 }
config.lazySet(Server.tcpPort) { it[basePort] + 1 }
```

Find item with specified name, and associate it with lazy thunk (unsafe API):

```kotlin
config.lazySet("server.port") { it[basePort] + 1 }
config.lazySet("server.tcpPort") { it[basePort] + 1 }
```

### Export value in config as property

Export a read-write property from value in config:

```kotlin
var port by config.property(Server.port)
var port by config.property(Server.tcpPort)
port = 9090
check(port == 9090)
```

Export a read-only property from value in config:

```kotlin
val port by config.property(Server.port)
val port by config.property(Server.tcpPort)
check(port == 9090)
```

### Fork from another config

```kotlin
val config = Config { addSpec(Server) }
config[Server.port] = 1000
config[Server.tcpPort] = 1000
// fork from parent config
val childConfig = config.withLayer("child")
// child config inherit values from parent config
check(childConfig[Server.port] == 1000)
check(childConfig[Server.tcpPort] == 1000)
// modifications in parent config affect values in child config
config[Server.port] = 2000
check(config[Server.port] == 2000)
check(childConfig[Server.port] == 2000)
config[Server.tcpPort] = 2000
check(config[Server.tcpPort] == 2000)
check(childConfig[Server.tcpPort] == 2000)
// modifications in child config don't affect values in parent config
childConfig[Server.port] = 3000
check(config[Server.port] == 2000)
check(childConfig[Server.port] == 3000)
childConfig[Server.tcpPort] = 3000
check(config[Server.tcpPort] == 2000)
check(childConfig[Server.tcpPort] == 3000)
```

## Load values from source
Expand Down Expand Up @@ -752,6 +752,7 @@ These features include:

- `FAIL_ON_UNKNOWN_PATH`: feature that determines what happens when unknown paths appear in the source. If enabled, an exception is thrown when loading from the source to indicate it contains unknown paths. This feature is disabled by default.
- `LOAD_KEYS_CASE_INSENSITIVELY`: feature that determines whether loading keys from sources case-insensitively. This feature is disabled by default except for system environment.
- `LOAD_KEYS_AS_LITTLE_CAMEL_CASE`: feature that determines whether loading keys from sources as little camel case. This feature is enabled by default.
- `OPTIONAL_SOURCE_BY_DEFAULT`: feature that determines whether sources are optional by default. This feature is disabled by default.
- `SUBSTITUTE_SOURCE_BEFORE_LOADED`: feature that determines whether sources should be substituted before loaded into config. This feature is enabled by default.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,22 +20,22 @@

public class ServerInJava {
private String host;
private Integer port;
private Integer tcpPort;

public ServerInJava(String host, Integer port) {
public ServerInJava(String host, Integer tcpPort) {
this.host = host;
this.port = port;
this.tcpPort = tcpPort;
}

public ServerInJava(Config config) {
this(config.get(ServerSpecInJava.host), config.get(ServerSpecInJava.port));
this(config.get(ServerSpecInJava.host), config.get(ServerSpecInJava.tcpPort));
}

public String getHost() {
return host;
}

public Integer getPort() {
return port;
public Integer getTcpPort() {
return tcpPort;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ public class ServerSpecInJava {
public static final OptionalItem<String> host =
new OptionalItem<String>(spec, "host", "0.0.0.0") {};

public static final RequiredItem<Integer> port = new RequiredItem<Integer>(spec, "port") {};
public static final RequiredItem<Integer> tcpPort = new RequiredItem<Integer>(spec, "tcpPort") {};
}
16 changes: 8 additions & 8 deletions konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Config.kt
Original file line number Diff line number Diff line change
Expand Up @@ -37,22 +37,22 @@ fun main(args: Array<String>) {
config.contains("server.host")
// or
"server.host" in config
config[Server.port] = 80
config["server.port"] = 80
config[Server.tcpPort] = 80
config["server.tcpPort"] = 80
config.containsRequired()
config.validateRequired()
config.unset(Server.port)
config.unset("server.port")
config.unset(Server.tcpPort)
config.unset("server.tcpPort")
val basePort by ConfigSpec("server").required<Int>()
config.lazySet(Server.port) { it[basePort] + 1 }
config.lazySet("server.port") { it[basePort] + 1 }
config.lazySet(Server.tcpPort) { it[basePort] + 1 }
config.lazySet("server.tcpPort") { it[basePort] + 1 }
run {
var port by config.property(Server.port)
var port by config.property(Server.tcpPort)
port = 9090
check(port == 9090)
}
run {
val port by config.property(Server.port)
val port by config.property(Server.tcpPort)
check(port == 9090)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ import com.uchuhimo.konf.source.json.toJson

fun main(args: Array<String>) {
val config = Config { addSpec(Server) }
config[Server.port] = 1000
config[Server.tcpPort] = 1000
run {
val map = config.toMap()
}
Expand All @@ -38,5 +38,5 @@ fun main(args: Array<String>) {
val newConfig = Config {
addSpec(Server)
}.from.json.file(file)
check(config == newConfig)
check(config.toMap() == newConfig.toMap())
}
16 changes: 8 additions & 8 deletions konf-all/src/snippet/kotlin/com/uchuhimo/konf/snippet/Fork.kt
Original file line number Diff line number Diff line change
Expand Up @@ -20,17 +20,17 @@ import com.uchuhimo.konf.Config

fun main(args: Array<String>) {
val config = Config { addSpec(Server) }
config[Server.port] = 1000
config[Server.tcpPort] = 1000
// fork from parent config
val childConfig = config.withLayer("child")
// child config inherit values from parent config
check(childConfig[Server.port] == 1000)
check(childConfig[Server.tcpPort] == 1000)
// modifications in parent config affect values in child config
config[Server.port] = 2000
check(config[Server.port] == 2000)
check(childConfig[Server.port] == 2000)
config[Server.tcpPort] = 2000
check(config[Server.tcpPort] == 2000)
check(childConfig[Server.tcpPort] == 2000)
// modifications in child config don't affect values in parent config
childConfig[Server.port] = 3000
check(config[Server.port] == 2000)
check(childConfig[Server.port] == 3000)
childConfig[Server.tcpPort] = 3000
check(config[Server.tcpPort] == 2000)
check(childConfig[Server.tcpPort] == 3000)
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import java.io.File

object ServerSpec : ConfigSpec() {
val host by optional("0.0.0.0")
val port by required<Int>()
val tcpPort by required<Int>()
}

fun main(args: Array<String>) {
Expand All @@ -36,7 +36,7 @@ fun main(args: Array<String>) {
"""
server:
host: 127.0.0.1
port: 8080
tcp_port: 8080
""".trimIndent()
)
file.deleteOnExit()
Expand All @@ -60,7 +60,7 @@ fun main(args: Array<String>) {
.from.env()
.from.systemProperties()
}
val server = Server(config[ServerSpec.host], config[ServerSpec.port])
val server = Server(config[ServerSpec.host], config[ServerSpec.tcpPort])
server.start()
run {
val server = Config()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import java.io.ObjectOutputStream

fun main(args: Array<String>) {
val config = Config { addSpec(Server) }
config[Server.port] = 1000
config[Server.tcpPort] = 1000
val map = config.toMap()
val newMap = createTempFile().run {
ObjectOutputStream(outputStream()).use {
Expand All @@ -36,5 +36,5 @@ fun main(args: Array<String>) {
val newConfig = Config {
addSpec(Server)
}.from.map.kv(newMap)
check(config == newConfig)
check(config.toMap() == newConfig.toMap())
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ package com.uchuhimo.konf.snippet
import com.uchuhimo.konf.Config
import com.uchuhimo.konf.ConfigSpec

data class Server(val host: String, val port: Int) {
constructor(config: Config) : this(config[Server.host], config[Server.port])
data class Server(val host: String, val tcpPort: Int) {
constructor(config: Config) : this(config[Server.host], config[Server.tcpPort])

fun start() {}

companion object : ConfigSpec("server") {
val host by optional("0.0.0.0", description = "host IP of server")
val port by required<Int>(description = "port of server")
val nextPort by lazy { config -> config[port] + 1 }
val tcpPort by required<Int>(description = "port of server")
val nextPort by lazy { config -> config[tcpPort] + 1 }
}
}
2 changes: 1 addition & 1 deletion konf-all/src/snippet/resources/server.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"server": {
"host": "127.0.0.1",
"port": 8080
"tcp_port": 8080
}
}
Loading

0 comments on commit d5ed231

Please sign in to comment.