From 86dd10dda71d8a642c908f81bee7abbc933b79a4 Mon Sep 17 00:00:00 2001 From: 00JCIV00 Date: Tue, 23 Jul 2024 13:34:36 -0400 Subject: [PATCH] Fixed Boolean parsing issue w/ Value Aliases - Fixed a parsing bug for Boolean Options if `bool` is aliased to something else. - Created the new `childTypeName()` method for `Value.Custom` to be a companion for `childType()`. The former will provide an aliased name if available. --- examples/covademo.zig | 4 ++++ src/Option.zig | 6 +++--- src/Value.zig | 19 +++++++++++++++---- src/cova.zig | 6 +++--- 4 files changed, 25 insertions(+), 10 deletions(-) diff --git a/examples/covademo.zig b/examples/covademo.zig index 30c233f..30f6d27 100644 --- a/examples/covademo.zig +++ b/examples/covademo.zig @@ -182,6 +182,10 @@ pub const CommandT = Command.Custom(.{ .ChildT = []const u8, .alias = "text", }, + .{ + .ChildT = bool, + .alias = "toggle", + } } }, //.global_usage_fn = struct{ diff --git a/src/Option.zig b/src/Option.zig index 3bd3e31..7a73282 100644 --- a/src/Option.zig +++ b/src/Option.zig @@ -286,7 +286,7 @@ pub fn Custom(comptime config: Config) type { // return helpFn(self, writer, self._alloc orelse return error.OptionNotInitialized); //} if (typeHelpFn: { - const val_child_type = self.val.childType(); + const val_child_type = self.val.childTypeName(); for (config.child_type_help_fns orelse break :typeHelpFn null) |elm| { if (mem.eql(u8, @typeName(elm.ChildT), val_child_type)) break :typeHelpFn elm.help_fn; @@ -313,7 +313,7 @@ pub fn Custom(comptime config: Config) type { // return usageFn(self, writer, self._alloc orelse return error.OptionNotInitialized); //} if (typeUsageFn: { - const val_child_type = self.val.childType(); + const val_child_type = self.val.childTypeName(); for (config.child_type_usage_fns orelse break :typeUsageFn null) |elm| { if (mem.eql(u8, @typeName(elm.ChildT), val_child_type)) break :typeUsageFn elm.usage_fn; @@ -329,7 +329,7 @@ pub fn Custom(comptime config: Config) type { if (long_prefix != null and self.long_name != null) long_prefix.? else "", if (long_prefix != null) self.long_name orelse "" else "", //self.val.name(), - self.val.childType(), + self.val.childTypeName(), }); } diff --git a/src/Value.zig b/src/Value.zig index 292f630..9fd88aa 100644 --- a/src/Value.zig +++ b/src/Value.zig @@ -698,8 +698,19 @@ pub fn Custom(comptime config: Config) type { }; } /// Get the inner Typed Value's Child Type Name. - /// This is where aliasing happens via `Value.Typed.alias_child_type` or `Value.Config.child_type_aliases`. + /// This will provide the actual Child Type Name without aliasing. pub fn childType(self: *const @This()) []const u8 { + @setEvalBranchQuota(config.max_int_bit_width * 10); + return switch (meta.activeTag(self.*.generic)) { + inline else => |tag| typeName: { + const val = @field(self.*.generic, @tagName(tag)); + break :typeName @typeName(@TypeOf(val).ChildT); + } + }; + } + /// Get the inner Typed Value's Child Type Name. + /// This is where aliasing happens via `Value.Typed.alias_child_type` or `Value.Config.child_type_aliases`. + pub fn childTypeName(self: *const @This()) []const u8 { @setEvalBranchQuota(config.max_int_bit_width * 10); return switch (meta.activeTag(self.*.generic)) { inline else => |tag| typeName: { @@ -894,7 +905,7 @@ pub fn Custom(comptime config: Config) type { try writer.print("{s}", .{ @tagName(meta.activeTag(self.generic)) }); try writer.print("{s}: Type: {s}, Set: {any}", .{ self.name(), - self.childType(), + self.childTypeName(), self.isSet(), }); } @@ -908,7 +919,7 @@ pub fn Custom(comptime config: Config) type { } } if (global_help_fn) |helpFn| return helpFn(self, writer, self.allocator() orelse return error.ValueNotInitialized); - try writer.print(vals_help_fmt, .{ self.name(), self.childType(), self.description() }); + try writer.print(vals_help_fmt, .{ self.name(), self.childTypeName(), self.description() }); } /// Creates the Usage message for this Value and Writes it to the provided Writer (`writer`). pub fn usage(self: *const @This(), writer: anytype) !void { @@ -919,7 +930,7 @@ pub fn Custom(comptime config: Config) type { } } if (global_usage_fn) |usageFn| return usageFn(self, writer, self.allocator() orelse return error.ValueNotInitialized); - try writer.print(vals_usage_fmt, .{ self.name(), self.childType() }); + try writer.print(vals_usage_fmt, .{ self.name(), self.childTypeName() }); } /// Initialize this Value with the provided Allocator (`alloc`). diff --git a/src/cova.zig b/src/cova.zig index 32e76af..9431656 100644 --- a/src/cova.zig +++ b/src/cova.zig @@ -369,10 +369,10 @@ fn parseArgsCtx( else { parseOpt(args, OptionT, opt) catch { if (cmd.allow_inheritable_opts) continue :inheritOpts; - log.err("Could not parse Option '{c}{?c}: {s}'.", .{ + log.err("Could not parse Option '{c}{?c}: {s}'.", .{ short_pf, - opt.short_name, - opt.name + opt.short_name, + opt.name, }); try errReaction(parse_config.err_reaction, opt, writer); try writer.print("\n", .{});