diff options
Diffstat (limited to 'example')
| -rw-r--r-- | example/README.md.template | 11 | ||||
| -rw-r--r-- | example/subcommands.zig | 96 |
2 files changed, 106 insertions, 1 deletions
diff --git a/example/README.md.template b/example/README.md.template index d234dcd..bcd3774 100644 --- a/example/README.md.template +++ b/example/README.md.template | |||
| @@ -63,7 +63,7 @@ The result will contain an `args` field and a `positionals` field. `args` will h | |||
| 63 | for each none positional parameter of your program. The name of the field will be the longest | 63 | for each none positional parameter of your program. The name of the field will be the longest |
| 64 | name of the parameter. `positionals` be a tuple with one field for each positional parameter. | 64 | name of the parameter. `positionals` be a tuple with one field for each positional parameter. |
| 65 | 65 | ||
| 66 | The fields in `args` and `psotionals` are typed. The type is based on the name of the value the | 66 | The fields in `args` and `postionals` are typed. The type is based on the name of the value the |
| 67 | parameter takes. Since `--number` takes a `usize` the field `res.args.number` has the type `usize`. | 67 | parameter takes. Since `--number` takes a `usize` the field `res.args.number` has the type `usize`. |
| 68 | 68 | ||
| 69 | Note that this is only the case because `clap.parsers.default` has a field called `usize` which | 69 | Note that this is only the case because `clap.parsers.default` has a field called `usize` which |
| @@ -74,6 +74,15 @@ contains a parser that returns `usize`. You can pass in something other than | |||
| 74 | {s} | 74 | {s} |
| 75 | ``` | 75 | ``` |
| 76 | 76 | ||
| 77 | ### Subcommands | ||
| 78 | |||
| 79 | There is an option for `clap.parse` and `clap.parseEx` called `terminating_positional`. It allows | ||
| 80 | for users of `clap` to implement subcommands in their cli application: | ||
| 81 | |||
| 82 | ```zig | ||
| 83 | {s} | ||
| 84 | ``` | ||
| 85 | |||
| 77 | ### `streaming.Clap` | 86 | ### `streaming.Clap` |
| 78 | 87 | ||
| 79 | The `streaming.Clap` is the base of all the other parsers. It's a streaming parser that uses an | 88 | The `streaming.Clap` is the base of all the other parsers. It's a streaming parser that uses an |
diff --git a/example/subcommands.zig b/example/subcommands.zig new file mode 100644 index 0000000..531a4d6 --- /dev/null +++ b/example/subcommands.zig | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | // These are our subcommands | ||
| 2 | const SubCommands = enum { | ||
| 3 | help, | ||
| 4 | math, | ||
| 5 | }; | ||
| 6 | |||
| 7 | const main_parsers = .{ | ||
| 8 | .command = clap.parsers.enumeration(SubCommands), | ||
| 9 | }; | ||
| 10 | |||
| 11 | // The parameters for main. Parameters for the subcommands are specified further down | ||
| 12 | const main_params = clap.parseParamsComptime( | ||
| 13 | \\-h, --help Display this help and exit. | ||
| 14 | \\<command> | ||
| 15 | \\ | ||
| 16 | ); | ||
| 17 | |||
| 18 | // To pass around arguments returned by clap, `clap.Result` and `clap.ResultEx` can be used to | ||
| 19 | // get the return type of `clap.parse` and `clap.parseEx` | ||
| 20 | const MainArgs = clap.ResultEx(clap.Help, &main_params, main_parsers); | ||
| 21 | |||
| 22 | pub fn main() !void { | ||
| 23 | var gpa_state = std.heap.GeneralPurposeAllocator(.{}){}; | ||
| 24 | const gpa = gpa_state.allocator(); | ||
| 25 | defer _ = gpa_state.deinit(); | ||
| 26 | |||
| 27 | var iter = try std.process.ArgIterator.initWithAllocator(gpa); | ||
| 28 | defer iter.deinit(); | ||
| 29 | |||
| 30 | _ = iter.next(); | ||
| 31 | |||
| 32 | var diag = clap.Diagnostic{}; | ||
| 33 | var res = clap.parseEx(clap.Help, &main_params, main_parsers, &iter, .{ | ||
| 34 | .diagnostic = &diag, | ||
| 35 | .allocator = gpa, | ||
| 36 | |||
| 37 | // Terminate the parsing of arguments after parsing the first positional (0 is passed here | ||
| 38 | // because parsed positionals are, like slices and arrays, indexed starting at 0). | ||
| 39 | // | ||
| 40 | // This will terminate the parsing after parsing the subcommand enum and leave `iter` not | ||
| 41 | // fully consumed. It can then be reused to parse the arguments for subcommands | ||
| 42 | .terminating_positional = 0, | ||
| 43 | }) catch |err| { | ||
| 44 | diag.report(std.io.getStdErr().writer(), err) catch {}; | ||
| 45 | return err; | ||
| 46 | }; | ||
| 47 | defer res.deinit(); | ||
| 48 | |||
| 49 | if (res.args.help != 0) | ||
| 50 | std.debug.print("--help\n", .{}); | ||
| 51 | |||
| 52 | const command = res.positionals[0] orelse return error.MissingCommand; | ||
| 53 | switch (command) { | ||
| 54 | .help => std.debug.print("--help\n", .{}), | ||
| 55 | .math => try mathMain(gpa, &iter, res), | ||
| 56 | } | ||
| 57 | } | ||
| 58 | |||
| 59 | fn mathMain(gpa: std.mem.Allocator, iter: *std.process.ArgIterator, main_args: MainArgs) !void { | ||
| 60 | // The parent arguments are not used it, but there are cases where it might be useful, so the | ||
| 61 | // example shows how to pass the arguments around. | ||
| 62 | _ = main_args; | ||
| 63 | |||
| 64 | // The parameters for the subcommand | ||
| 65 | const params = comptime clap.parseParamsComptime( | ||
| 66 | \\-h, --help Display this help and exit. | ||
| 67 | \\-a, --add Add the two numbers | ||
| 68 | \\-s, --sub Subtract the two numbers | ||
| 69 | \\<isize> | ||
| 70 | \\<isize> | ||
| 71 | \\ | ||
| 72 | ); | ||
| 73 | |||
| 74 | // Here we pass the partially parsed argument iterator | ||
| 75 | var diag = clap.Diagnostic{}; | ||
| 76 | var res = clap.parseEx(clap.Help, ¶ms, clap.parsers.default, iter, .{ | ||
| 77 | .diagnostic = &diag, | ||
| 78 | .allocator = gpa, | ||
| 79 | }) catch |err| { | ||
| 80 | diag.report(std.io.getStdErr().writer(), err) catch {}; | ||
| 81 | return err; | ||
| 82 | }; | ||
| 83 | defer res.deinit(); | ||
| 84 | |||
| 85 | const a = res.positionals[0] orelse return error.MissingArg1; | ||
| 86 | const b = res.positionals[1] orelse return error.MissingArg1; | ||
| 87 | if (res.args.help != 0) | ||
| 88 | std.debug.print("--help\n", .{}); | ||
| 89 | if (res.args.add != 0) | ||
| 90 | std.debug.print("added: {}\n", .{a + b}); | ||
| 91 | if (res.args.sub != 0) | ||
| 92 | std.debug.print("subtracted: {}\n", .{a - b}); | ||
| 93 | } | ||
| 94 | |||
| 95 | const clap = @import("clap"); | ||
| 96 | const std = @import("std"); | ||