From 5f7b75d5523d9581eca5a72a362868ff517992e8 Mon Sep 17 00:00:00 2001 From: Jimmi Holst Christensen Date: Fri, 25 Feb 2022 19:40:00 +0100 Subject: Allow for clap to parse argument values into types This changes - `.flag`, `.option`, `.options` and `.positionals` are now just fields you access on the result of `parse` and `parseEx`. - `clap.ComptimeClap` has been removed. - `clap.StreamingClap` is now called `clap.streaming.Clap` - `parse` and `parseEx` now takes a `value_parsers` argument that provides the parsers to parse values. - Remove `helpEx`, `helpFull`, `usageEx` and `usageFull`. They now just expect `Id` to have methods for getting the description and value texts. --- example/README.md.template | 51 ++++++++++++++++------------------------------ example/help.zig | 8 ++++---- example/simple-error.zig | 13 ------------ example/simple-ex.zig | 39 ++++++++++++++++------------------- example/simple.zig | 24 ++++++++++++---------- example/streaming-clap.zig | 2 +- example/usage.zig | 14 ++++++------- 7 files changed, 59 insertions(+), 92 deletions(-) delete mode 100644 example/simple-error.zig (limited to 'example') diff --git a/example/README.md.template b/example/README.md.template index 7f5c545..9fbc1cc 100644 --- a/example/README.md.template +++ b/example/README.md.template @@ -27,33 +27,24 @@ The simplest way to use this library is to just call the `clap.parse` function. {s} ``` -The data structure returned has lookup speed on par with array access (`arr[i]`) and validates -that the strings you pass to `option`, `options` and `flag` are actually parameters that the -program can take: +The result will contain an `args` field and a `positionals` field. `args` will have one field +for each none positional parameter of your program. The name of the field will be the longest +name of the parameter. + +The fields in `args` are typed. The type is based on the name of the value the parameter takes. +Since `--number` takes a `usize` the field `res.args.number` has the type `usize`. + +Note that this is only the case because `clap.parsers.default` has a field called `usize` which +contains a parser that returns `usize`. You can pass in something other than `clap.parsers.default` +if you want some other mapping. ```zig {s} ``` -``` -zig-clap/clap/comptime.zig:109:17: error: --helps is not a parameter. - @compileError(name ++ " is not a parameter."); - ^ -zig-clap/clap/comptime.zig:77:45: note: called from here - const param = comptime findParam(name); - ^ -zig-clap/clap.zig:238:31: note: called from here - return a.clap.flag(name); - ^ -zig-clap/example/simple-error.zig:16:18: note: called from here - _ = args.flag("--helps"); -``` - -There is also a `parseEx` variant that takes an argument iterator. +### `streaming.Clap` -### `StreamingClap` - -The `StreamingClap` is the base of all the other parsers. It's a streaming parser that uses an +The `streaming.Clap` is the base of all the other parsers. It's a streaming parser that uses an `args.Iterator` to provide it with arguments lazily. ```zig @@ -65,8 +56,9 @@ is generated at runtime. ### `help` -The `help`, `helpEx` and `helpFull` are functions for printing a simple list of all parameters the -program can take. +The `help` prints a simple list of all parameters the program can take. It expects the +`Id` to have a `description` method and an `value` method so that it can provide that +in the output. ```zig {s} @@ -78,19 +70,10 @@ $ zig-out/bin/help --help -v, --version Output version information and exit. ``` -The `help` functions are the simplest to call. It only takes an `OutStream` and a slice of -`Param(Help)`. - -The `helpEx` is the generic version of `help`. It can print a help message for any -`Param` give that the caller provides functions for getting the help and value strings. - -The `helpFull` is even more generic, allowing the functions that get the help and value strings -to return errors and take a context as a parameter. - ### `usage` -The `usage`, `usageEx` and `usageFull` are functions for printing a small abbreviated version -of the help message. +The `usage` prints a small abbreviated version of the help message. It expects the `Id` +to have a `value` method so it can provide that in the output. ```zig {s} diff --git a/example/help.zig b/example/help.zig index de3b707..f3edb58 100644 --- a/example/help.zig +++ b/example/help.zig @@ -7,12 +7,12 @@ pub fn main() !void { clap.parseParam("-v, --version Output version information and exit.") catch unreachable, }; - var args = try clap.parse(clap.Help, ¶ms, .{}); - defer args.deinit(); + var res = try clap.parse(clap.Help, ¶ms, clap.parsers.default, .{}); + defer res.deinit(); // clap.help is a function that can print a simple help message, given a // slice of Param(Help). There is also a helpEx, which can print a // help message for any Param, but it is more verbose to call. - if (args.flag("--help")) - return clap.help(std.io.getStdErr().writer(), ¶ms); + if (res.args.help) + return clap.help(std.io.getStdErr().writer(), clap.Help, ¶ms); } diff --git a/example/simple-error.zig b/example/simple-error.zig deleted file mode 100644 index c04a9c6..0000000 --- a/example/simple-error.zig +++ /dev/null @@ -1,13 +0,0 @@ -const clap = @import("clap"); -const std = @import("std"); - -pub fn main() !void { - const params = comptime [_]clap.Param(clap.Help){ - clap.parseParam("-h, --help Display this help and exit.") catch unreachable, - }; - - var args = try clap.parse(clap.Help, ¶ms, .{}); - defer args.deinit(); - - _ = args.flag("--helps"); -} diff --git a/example/simple-ex.zig b/example/simple-ex.zig index d2dc77e..6cb4c3f 100644 --- a/example/simple-ex.zig +++ b/example/simple-ex.zig @@ -6,43 +6,38 @@ const io = std.io; const process = std.process; pub fn main() !void { - const allocator = std.heap.page_allocator; - // First we specify what parameters our program can take. // We can use `parseParam` to parse a string to a `Param(Help)` const params = comptime [_]clap.Param(clap.Help){ - clap.parseParam("-h, --help Display this help and exit. ") catch unreachable, - clap.parseParam("-n, --number An option parameter, which takes a value.") catch unreachable, + clap.parseParam("-h, --help Display this help and exit.") catch unreachable, + clap.parseParam("-n, --number An option parameter, which takes a value.") catch unreachable, clap.parseParam("-s, --string ... An option parameter which can be specified multiple times.") catch unreachable, - clap.parseParam("...") catch unreachable, + clap.parseParam("...") catch unreachable, }; - var iter = try process.ArgIterator.initWithAllocator(allocator); - defer iter.deinit(); - - // Skip exe argument - _ = iter.next(); + // Declare our own parsers which are used to map the argument strings to other + // types. + const parsers = comptime .{ + .STR = clap.parsers.string, + .FILE = clap.parsers.string, + .INT = clap.parsers.int(usize, 10), + }; - // Initalize our diagnostics, which can be used for reporting useful errors. - // This is optional. You can also pass `.{}` to `clap.parse` if you don't - // care about the extra information `Diagnostics` provides. var diag = clap.Diagnostic{}; - var args = clap.parseEx(clap.Help, ¶ms, &iter, .{ - .allocator = allocator, + var res = clap.parse(clap.Help, ¶ms, parsers, .{ .diagnostic = &diag, }) catch |err| { - // Report useful error and exit diag.report(io.getStdErr().writer(), err) catch {}; return err; }; - defer args.deinit(); + defer res.deinit(); - if (args.flag("--help")) + if (res.args.help) debug.print("--help\n", .{}); - if (args.option("--number")) |n| - debug.print("--number = {s}\n", .{n}); - for (args.options("--string")) |s| + if (res.args.number) |n| + debug.print("--number = {}\n", .{n}); + for (res.args.string) |s| debug.print("--string = {s}\n", .{s}); - for (args.positionals()) |pos| + for (res.positionals) |pos| debug.print("{s}\n", .{pos}); } diff --git a/example/simple.zig b/example/simple.zig index ff6d301..11e975e 100644 --- a/example/simple.zig +++ b/example/simple.zig @@ -8,29 +8,31 @@ pub fn main() !void { // First we specify what parameters our program can take. // We can use `parseParam` to parse a string to a `Param(Help)` const params = comptime [_]clap.Param(clap.Help){ - clap.parseParam("-h, --help Display this help and exit. ") catch unreachable, - clap.parseParam("-n, --number An option parameter, which takes a value.") catch unreachable, - clap.parseParam("-s, --string ... An option parameter which can be specified multiple times.") catch unreachable, - clap.parseParam("...") catch unreachable, + clap.parseParam("-h, --help Display this help and exit.") catch unreachable, + clap.parseParam("-n, --number An option parameter, which takes a value.") catch unreachable, + clap.parseParam("-s, --string ... An option parameter which can be specified multiple times.") catch unreachable, + clap.parseParam("...") catch unreachable, }; // Initalize our diagnostics, which can be used for reporting useful errors. // This is optional. You can also pass `.{}` to `clap.parse` if you don't // care about the extra information `Diagnostics` provides. var diag = clap.Diagnostic{}; - var args = clap.parse(clap.Help, ¶ms, .{ .diagnostic = &diag }) catch |err| { + var res = clap.parse(clap.Help, ¶ms, clap.parsers.default, .{ + .diagnostic = &diag, + }) catch |err| { // Report useful error and exit diag.report(io.getStdErr().writer(), err) catch {}; return err; }; - defer args.deinit(); + defer res.deinit(); - if (args.flag("--help")) + if (res.args.help) debug.print("--help\n", .{}); - if (args.option("--number")) |n| - debug.print("--number = {s}\n", .{n}); - for (args.options("--string")) |s| + if (res.args.number) |n| + debug.print("--number = {}\n", .{n}); + for (res.args.string) |s| debug.print("--string = {s}\n", .{s}); - for (args.positionals()) |pos| + for (res.positionals) |pos| debug.print("{s}\n", .{pos}); } diff --git a/example/streaming-clap.zig b/example/streaming-clap.zig index a7ab7d8..cacda56 100644 --- a/example/streaming-clap.zig +++ b/example/streaming-clap.zig @@ -32,7 +32,7 @@ pub fn main() !void { // This is optional. You can also leave the `diagnostic` field unset if you // don't care about the extra information `Diagnostic` provides. var diag = clap.Diagnostic{}; - var parser = clap.StreamingClap(u8, process.ArgIterator){ + var parser = clap.streaming.Clap(u8, process.ArgIterator){ .params = ¶ms, .iter = &iter, .diagnostic = &diag, diff --git a/example/usage.zig b/example/usage.zig index 368a6b3..20d4736 100644 --- a/example/usage.zig +++ b/example/usage.zig @@ -3,17 +3,17 @@ const std = @import("std"); pub fn main() !void { const params = comptime [_]clap.Param(clap.Help){ - clap.parseParam("-h, --help Display this help and exit. ") catch unreachable, - clap.parseParam("-v, --version Output version information and exit. ") catch unreachable, - clap.parseParam(" --value An option parameter, which takes a value.") catch unreachable, + clap.parseParam("-h, --help Display this help and exit.") catch unreachable, + clap.parseParam("-v, --version Output version information and exit.") catch unreachable, + clap.parseParam(" --value An option parameter, which takes a value.") catch unreachable, }; - var args = try clap.parse(clap.Help, ¶ms, .{}); - defer args.deinit(); + var res = try clap.parse(clap.Help, ¶ms, clap.parsers.default, .{}); + defer res.deinit(); // clap.usage is a function that can print a simple usage message, given a // slice of Param(Help). There is also a usageEx, which can print a // usage message for any Param, but it is more verbose to call. - if (args.flag("--help")) - return clap.usage(std.io.getStdErr().writer(), ¶ms); + if (res.args.help) + return clap.usage(std.io.getStdErr().writer(), clap.Help, ¶ms); } -- cgit v1.2.3