summaryrefslogtreecommitdiff
path: root/example/subcommands.zig
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--example/subcommands.zig96
1 files changed, 96 insertions, 0 deletions
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
2const SubCommands = enum {
3 help,
4 math,
5};
6
7const main_parsers = .{
8 .command = clap.parsers.enumeration(SubCommands),
9};
10
11// The parameters for main. Parameters for the subcommands are specified further down
12const 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`
20const MainArgs = clap.ResultEx(clap.Help, &main_params, main_parsers);
21
22pub 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
59fn 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, &params, 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
95const clap = @import("clap");
96const std = @import("std");