33## Overview
44
55zig-cli includes a powerful configuration system supporting three popular formats:
6+
67- ** TOML** - Simple, readable configuration format
78- ** JSONC** - JSON with Comments (also handles standard JSON)
89- ** JSON5** - JSON with extended syntax (more JavaScript-like)
@@ -14,18 +15,21 @@ zig-cli includes a powerful configuration system supporting three popular format
1415Each format has its own strengths:
1516
1617** TOML:**
18+
1719- Simple, INI-like syntax
1820- Great for human editing
1921- Native support for nested tables
2022- Comments with ` # `
2123
2224** JSONC:**
25+
2326- JSON with ` // ` and ` /* */ ` comments
2427- Trailing commas allowed
2528- Familiar to JavaScript developers
2629- Works with standard JSON files too
2730
2831** JSON5:**
32+
2933- Unquoted object keys
3034- Single and double quotes for strings
3135- Trailing commas
@@ -44,7 +48,7 @@ const AppConfig = struct {
4448 host: []const u8,
4549 port: u16,
4650 },
47- log_level : enum { debug, info, warn, @"error" } = .info,
51+ log*level : enum { debug, info, warn, @"error" } = .info,
4852 debug: bool = false,
4953};
5054
@@ -69,6 +73,7 @@ defer config.deinit();
6973```
7074
7175Search locations (in order):
76+
72771 . ` ./myapp.{toml,json5,jsonc,json} `
73782 . ` ./.config/myapp.{toml,json5,jsonc,json} `
74793 . ` ~/.config/myapp/myapp.{toml,json5,jsonc,json} `
@@ -80,19 +85,19 @@ First found file is loaded.
8085For cases where you don't have a schema, use the raw ` Config ` type:
8186
8287``` zig
83- var raw_config = cli.config.Config.init(allocator);
84- defer raw_config .deinit();
88+ var raw*config = cli.config.Config.init(allocator);
89+ defer raw*config .deinit();
8590
86- try raw_config .loadFromFile("config.toml", .auto);
91+ try raw*config .loadFromFile("config.toml", .auto);
8792
8893// Typed getters with optional returns
89- const name = raw_config .getString("name"); // ?[]const u8
90- const port = raw_config .getInt("port"); // ?i64
91- const debug = raw_config .getBool("debug"); // ?bool
92- const timeout = raw_config .getFloat("timeout"); // ?f64
94+ const name = raw*config .getString("name"); // ?[]const u8
95+ const port = raw*config .getInt("port"); // ?i64
96+ const debug = raw*config .getBool("debug"); // ?bool
97+ const timeout = raw*config .getFloat("timeout"); // ?f64
9398
9499// Raw value access for complex types
95- const value = raw_config .get("database"); // ?*Value
100+ const value = raw*config .get("database"); // ?*Value
96101```
97102
98103### 5. Nested Configuration
@@ -127,18 +132,18 @@ timeout = 30
127132Auto-detect based on file extension:
128133
129134``` zig
130- try raw_config .loadFromFile("config.toml", .auto); // Detects TOML
131- try raw_config .loadFromFile("config.json5", .auto); // Detects JSON5
132- try raw_config .loadFromFile("config.jsonc", .auto); // Detects JSONC
133- try raw_config .loadFromFile("config.json", .auto); // Treats as JSONC
135+ try raw*config .loadFromFile("config.toml", .auto); // Detects TOML
136+ try raw*config .loadFromFile("config.json5", .auto); // Detects JSON5
137+ try raw*config .loadFromFile("config.jsonc", .auto); // Detects JSONC
138+ try raw*config .loadFromFile("config.json", .auto); // Treats as JSONC
134139```
135140
136141Or specify explicitly:
137142
138143``` zig
139- try raw_config .loadFromFile("myfile", .toml);
140- try raw_config .loadFromFile("myfile", .jsonc);
141- try raw_config .loadFromFile("myfile", .json5);
144+ try raw*config .loadFromFile("myfile", .toml);
145+ try raw*config .loadFromFile("myfile", .jsonc);
146+ try raw*config .loadFromFile("myfile", .json5);
142147```
143148
144149## Implementation Details
@@ -173,7 +178,7 @@ Unified `Value` type across all formats:
173178
174179``` zig
175180pub const Value = union(enum) {
176- null_value : void,
181+ null*value : void,
177182 boolean: bool,
178183 integer: i64,
179184 float: f64,
@@ -195,7 +200,7 @@ pub const Config = struct {
195200 // Loading
196201 pub fn loadFromFile(path, format) !void
197202 pub fn loadFromString(content, format) !void
198- pub fn discover(allocator, app_name ) !Config
203+ pub fn discover(allocator, app*name ) !Config
199204
200205 // Accessing
201206 pub fn get(key) ?*Value
@@ -217,7 +222,7 @@ The `ConfigLoader` provides the high-level typed API:
217222// These are available via cli.config namespace:
218223pub fn load(comptime T: type, allocator, path) !ConfigLoader(T)
219224pub fn loadFromString(comptime T: type, allocator, content, format) !ConfigLoader(T)
220- pub fn discover(comptime T: type, allocator, app_name ) !ConfigLoader(T)
225+ pub fn discover(comptime T: type, allocator, app*name ) !ConfigLoader(T)
221226```
222227
223228## Usage Examples
@@ -236,7 +241,7 @@ const ServerConfig = struct {
236241
237242pub fn main() !void {
238243 var gpa = std.heap.GeneralPurposeAllocator(.{}){};
239- defer _ = gpa.deinit();
244+ defer * = gpa.deinit();
240245 const allocator = gpa.allocator();
241246
242247 // Load typed config
@@ -284,22 +289,22 @@ fn serverAction(ctx: *cli.BaseCommand.ParseContext) !void {
284289### Untyped Config with Nested Values
285290
286291``` zig
287- var raw_config = cli.config.Config.init(allocator);
288- defer raw_config .deinit();
292+ var raw*config = cli.config.Config.init(allocator);
293+ defer raw*config .deinit();
289294
290- try raw_config .loadFromFile("config.toml", .auto);
295+ try raw*config .loadFromFile("config.toml", .auto);
291296
292297// Access nested database config
293- if (raw_config .get("database")) |db_value | {
294- if (db_value .* == .table) {
295- const db_table = &db_value .table;
298+ if (raw*config .get("database")) |db*value | {
299+ if (db*value .* == .table) {
300+ const db*table = &db*value .table;
296301
297- const host = if (db_table .get("host")) |h|
302+ const host = if (db*table .get("host")) |h|
298303 if (h == .string) h.string else "localhost"
299304 else
300305 "localhost";
301306
302- const port = if (db_table .get("port")) |p|
307+ const port = if (db*table .get("port")) |p|
303308 if (p == .integer) p.integer else 5432
304309 else
305310 5432;
@@ -376,6 +381,7 @@ zig build run-config
376381## Summary
377382
378383The configuration system provides:
384+
379385- ** 3 format parsers** with full feature support (TOML, JSONC, JSON5)
380386- ** Type-safe API** via ` cli.config.load(T, ...) ` for compile-time schema validation
381387- ** Untyped API** via ` cli.config.Config ` for dynamic config access
0 commit comments