all: continue organization and add bakery
The bakery bakes the user context type into an object so that it doesn't have to be specified over and over again. This ends up being a nicer way of specifying the CLI parameters, except for the fact that it requires a slightly odd comptime block construct due to `var` not working at the top level for some reason (and `comptime var` also not working).
This commit is contained in:
@@ -4,53 +4,51 @@ const noclip = @import("noclip");
|
||||
const context: []const u8 = "hello friend";
|
||||
const ContextType = @TypeOf(context);
|
||||
|
||||
const helpFlag = noclip.HelpFlag(.{ .UserContext = ContextType });
|
||||
const subcommand = blk: {
|
||||
var cmd = noclip.Command(ContextType, .{ .name = "subcommand", .help = "this a sub command" });
|
||||
cmd.add(cmd.defaultHelpFlag);
|
||||
cmd.add(cmd.StringOption{ .name = "meta", .short = "-m" });
|
||||
cmd.add(cmd.StringArgument{ .name = "sub" });
|
||||
break :blk cmd;
|
||||
};
|
||||
|
||||
const subData: noclip.CommandData = .{ .name = "subcommand", .help = "this a sub command" };
|
||||
const subFlag: noclip.StringOption(ContextType) = .{ .name = "meta", .short = "-m" };
|
||||
const subArg: noclip.StringArg(ContextType) = .{ .name = "sub" };
|
||||
const subSpec = .{ helpFlag, subFlag, subArg };
|
||||
const subCommand: noclip.CommandParser(subData, subSpec, ContextType, subCallback) = .{};
|
||||
const command = blk: {
|
||||
var cmd = noclip.Command(ContextType, .{ .name = "main", .help = "main CLI entry point" });
|
||||
cmd.add(cmd.Flag{ .name = "flag", .truthy = .{ .short = "-f", .long = "--flag" }, .falsy = .{ .long = "--no-flag" } });
|
||||
cmd.add(cmd.StringOption{
|
||||
.name = "input",
|
||||
.short = "-i",
|
||||
.long = "--input",
|
||||
.handler = printHandler,
|
||||
.envVar = "OPTS_INPUT",
|
||||
});
|
||||
cmd.add(cmd.StringOption{ .name = "output", .long = "--output", .default = "waoh" });
|
||||
cmd.add(cmd.Option(i32){ .name = "number", .short = "-n", .long = "--number" });
|
||||
cmd.add(cmd.StringArgument{ .name = "argument" });
|
||||
cmd.add(cmd.Argument(u32){ .name = "another", .default = 0 });
|
||||
|
||||
fn wrecker(zontext: ContextType, input: []const u8) ![]const u8 {
|
||||
std.debug.print("ctx: {s}\n", .{zontext});
|
||||
cmd.add(subcommand.Parser(subCallback));
|
||||
break :blk cmd;
|
||||
};
|
||||
|
||||
fn printHandler(ctx: ContextType, input: []const u8) ![]const u8 {
|
||||
std.debug.print("ctx: {s}\n", .{ctx});
|
||||
return input;
|
||||
}
|
||||
|
||||
const cdata: noclip.CommandData = .{ .name = "main", .help = "main CLI entry point" };
|
||||
const flagCheck: noclip.FlagOption(ContextType) = .{
|
||||
.name = "flag",
|
||||
.truthy = .{ .short = "-f", .long = "--flag" },
|
||||
.falsy = .{ .long = "--no-flag" },
|
||||
};
|
||||
const inputOption: noclip.StringOption(ContextType) = .{
|
||||
.name = "input",
|
||||
.short = "-i",
|
||||
.long = "--input",
|
||||
.handler = wrecker,
|
||||
.envVar = "OPTS_INPUT",
|
||||
};
|
||||
const outputOption: noclip.StringOption(ContextType) = .{ .name = "output", .long = "--output", .default = "waoh" };
|
||||
const numberOption: noclip.ValuedOption(.{ .Output = i32, .UserContext = ContextType }) = .{ .name = "number", .short = "-n", .long = "--number" };
|
||||
const argCheck: noclip.StringArg(ContextType) = .{ .name = "argument" };
|
||||
const argAgain: noclip.StringArg(ContextType) = .{ .name = "another", .default = "nope" };
|
||||
|
||||
const mainSpec = .{
|
||||
helpFlag,
|
||||
flagCheck,
|
||||
inputOption,
|
||||
outputOption,
|
||||
numberOption,
|
||||
argCheck,
|
||||
argAgain,
|
||||
subCommand,
|
||||
};
|
||||
|
||||
pub fn subCallback(_: ContextType, result: noclip.CommandResult(subSpec, ContextType)) !void {
|
||||
std.debug.print("subcommand {any}!!!\n", .{result});
|
||||
pub fn subCallback(_: ContextType, result: subcommand.CommandResult()) !void {
|
||||
std.debug.print(
|
||||
\\subcommand: {{
|
||||
\\ .meta = {s}
|
||||
\\ .sub = {s}
|
||||
\\}}
|
||||
\\
|
||||
,
|
||||
.{ result.meta, result.sub },
|
||||
);
|
||||
}
|
||||
|
||||
pub fn mainCommand(_: ContextType, result: noclip.CommandResult(mainSpec, ContextType)) !void {
|
||||
pub fn mainCommand(_: ContextType, result: command.CommandResult()) !void {
|
||||
std.debug.print(
|
||||
\\arguments: {{
|
||||
\\ .flag = {any}
|
||||
@@ -58,7 +56,7 @@ pub fn mainCommand(_: ContextType, result: noclip.CommandResult(mainSpec, Contex
|
||||
\\ .output = {s}
|
||||
\\ .number = {d}
|
||||
\\ .argument = {s}
|
||||
\\ .another = {s}
|
||||
\\ .another = {d}
|
||||
\\}}
|
||||
\\
|
||||
,
|
||||
@@ -74,7 +72,7 @@ pub fn mainCommand(_: ContextType, result: noclip.CommandResult(mainSpec, Contex
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
var command: noclip.CommandParser(cdata, mainSpec, ContextType, mainCommand) = .{};
|
||||
var parser = command.Parser(mainCommand);
|
||||
|
||||
var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
|
||||
defer arena.deinit();
|
||||
@@ -83,5 +81,5 @@ pub fn main() !void {
|
||||
var argit = try std.process.argsWithAllocator(allocator);
|
||||
_ = argit.next();
|
||||
|
||||
try command.execute(allocator, std.process.ArgIterator, &argit, context);
|
||||
try parser.execute(allocator, std.process.ArgIterator, &argit, context);
|
||||
}
|
||||
|
Reference in New Issue
Block a user