cfg
cfg - load, layer, query, decode, and write configuration.
const cfg = @import("cfg");
const Settings = struct {
server: struct { host: []const u8 = "localhost", port: u16 = 8080 } = .{},
token: ?[]const u8 = null,
};
// What the fields mean, from `field` specs; how they are spelled, per place.
const app = cfg.settings(Settings, field.Set(.{field.Spec(Settings){ .fields = .{
.token = .{ .help = "API token", .secret = true },
} }}), .{ .fields = .{ .token = .{ .env = "APP_TOKEN" } } });
var config: cfg.Config = try .initFor(app, gpa);
defer config.deinit();
if (try config.findFile(io, .{
.name = "app",
.dirs = &.{ ".", "$HOME/.config/app" },
})) |file| {
try config.loadFile(io, .cwd(), file, null, &diag);
}
config.useEnv(environ);
try config.automaticEnv("APP"); // APP_SERVER_PORT=9000
const settings = try config.decode(app, .{}, &diag);
Formats: JSON (and JSON with comments), TOML, YAML, dotenv, ZON, and INI (see Format).
Defaults may also come from a .zon file, which the compiler checks against the struct
when it is imported, so a misspelled or mistyped default does not build:
const defaults: Settings = @import("defaults.zon"); // .{ .server = .{ .port = 9000 } }
try config.setDefaults(app, defaults);
The module imports std and field, whose specs it shares with cli. It shares one
convention with cli besides: any type with
pub fn parse(text: []const u8) !T decodes from text, so Duration and ByteSize
work as configuration fields and as flag types.
Declarations
Config | Layers of configuration (defaults, files, environment, flags), queried and decoded. |
Diagnostic | Where and why a parse or a decode failed. |
Value | A configuration tree: a table, array, string, number, boolean, or null. |
Table | A tree's table: keys in insertion order. |
Array | A tree's array. |
Format | A configuration format: what Format.fromPath names, and its parse and write. |
Duration | A span of time, written 1h30m, 500ms: a field and flag type. |
ByteSize | A count of bytes, written 10MiB, 1.5GB: a field and flag type. |
DateTime | A date and time, as TOML and RFC 3339 write it. |
decode | Decodes a tree into a settings type or a plain Zig type. |
encode | Encodes a Zig value into a tree, each field under its own name. |
encodeAs | Encodes a value under the keys a settings type gives its fields. |
settings | A settings type: a struct, what its fields mean (a field.Set of specs), and the keys they are spelled with. |
Keys | The spellings settings takes: each field's key, old key, variable, and merging. |
Merge | How a list combines across layers. |
sourcesOf | Where else each value of a settings type can be set, for a command's help. |
DecodeOptions | How decode treats unknown keys, bounds, and warnings. |
DecodeError | What decode can fail with. |
infer | Infers the type of untyped text: true, 42, 1.5, 2024-01-01, or a string. |
glob | Whether text matches a pattern where * matches any run of bytes and ? one byte, as .glob checks and ignore lists use: glob(".*", ".cache"). |
diff | The leaves that differ between two trees. |
Change | One leaf that differs, as diff reports it. |
value | The tree: Value and its operations. |
path | Dotted key paths: server.port, servers.0.host, "a.b".c. |
json | JSON, and JSON with comments. |
toml | TOML 1.0. |
yaml | YAML 1.2, without the parts configuration does not use. |
dotenv | .env files. |
zon | ZON, Zig's object notation. |
ini | INI files. |
schema | JSON Schema for a settings struct, and checking a tree against one. |
edit | Changing a document in place, keeping its comments and layout. |
locate | Where a key is written in a document: its line and column. |
encrypted | Encrypted configuration files. |
migrate | Upgrading documents between schema versions. |
internal | The library's own parts, public for its files and for the curious, but not stable: they change in any release (see docs/stability.md). |