Config

The config source-stdlib module provides helpers for nested configuration dictionaries. It is useful for merging defaults, environment-specific override layers, parsed config files, and application settings passed into framework components.

import config;

let cfg = config.layer([
    {"debug": false, "db": {"host": "localhost", "port": 5432}},
    {"debug": true, "db": {"database": "app"}}
]);

io.println(config.require(cfg, "db.host"));
io.println(config.getOr(cfg, "cache.ttl", 300));

Functions

Function Returns Description
clone(data) dict<string, any> Shallow-copy a configuration dictionary
merge(base, overrides) dict<string, any> Recursively merge overrides into a copy of base
defaults(values, defaultValues) dict<string, any> Apply defaults first, then explicit values
layer(layers) dict<string, any> Merge a list of dictionaries from first to last
has(data, path) bool Test whether a dotted path exists
get(data, path) any Return a required dotted-path value or throw ValueError
getOr(data, path, fallback) any Return a dotted-path value or fallback
require(data, path) any Alias for get when the call site wants explicit required semantics
parse(format, text) Config Parse a serde-supported document into a Config object

merge is recursive only when both sides at a key are dictionaries. Otherwise the override value replaces the base value.

let base = {
    "app": {"name": "Geb", "debug": false},
    "cache": {"ttl": 60}
};

let local = {
    "app": {"debug": true},
    "cache": {"driver": "redis"}
};

let merged = config.merge(base, local);
io.println(merged["app"]["name"]);
io.println(merged["app"]["debug"]);
io.println(merged["cache"]["driver"]);

Dotted Paths

Dotted paths walk nested dictionaries. They do not parse list indexes.

let settings = {
    "db": {
        "primary": {
            "host": "localhost",
            "port": 5432
        }
    }
};

io.println(config.has(settings, "db.primary.host"));
io.println(config.get(settings, "db.primary.port"));
io.println(config.getOr(settings, "db.replica.host", "none"));

get and require throw ValueError when any path segment is missing. getOr returns the fallback if a segment is missing or a non-dictionary value is encountered before the end of the path.

Config

Config is an immutable-style wrapper around a cloned dictionary.

Method Returns Description
has(path) bool Test whether a dotted path exists
get(path) any Return a required dotted-path value
require(path) any Alias for get
getOr(path, fallback) any Return a value or fallback
toDict() dict<string, any> Return a shallow copy of the stored config
let cfg = config.Config({
    "mail": {"from": "noreply@example.com"}
});

io.println(cfg.require("mail.from"));
io.println(cfg.getOr("mail.transport", "smtp"));

Parsing

config.parse(format, text) delegates to serde.parse, so it supports the formats available through the serialization modules, such as json, yaml, toml, and xml where the parsed top-level value is an object.

let cfg = config.parse("json", `{"server":{"port":8080}}`);
io.println(cfg.require("server.port"));

Use Config.toDict() when an API expects a plain dictionary:

let options = cfg.toDict();