diff --git a/examples/covademo.zig b/examples/covademo.zig index 30f6d27..ddba942 100644 --- a/examples/covademo.zig +++ b/examples/covademo.zig @@ -619,6 +619,12 @@ pub fn main() !void { xor_opts_check, } ); + var main_opts = try main_cmd.getOpts(.{}); + if (main_opts.get("string_opt")) |str_opt| { + const opt_strs = try str_opt.val.getAllAs([]const u8); + log.debug("Option Strings (--string): {d}", .{ opt_strs.len }); + for (opt_strs, 0..) |str, idx| log.debug(" {d}. {s}", .{ idx, str }); + } //if (main_cmd.opts) |main_opts| { // for (main_opts) |opt| log.debug("-> Opt: {s}, Idx: {d}", .{ opt.name, opt.arg_idx orelse continue }); //} diff --git a/src/Value.zig b/src/Value.zig index 9fd88aa..e778f06 100644 --- a/src/Value.zig +++ b/src/Value.zig @@ -350,9 +350,9 @@ pub fn Typed(comptime SetT: type, comptime config: Config) type { else error.ValueNotSet; } - /// Get All Parsed and Validated Arguments of this Value. + /// Get All Parsed and Validated Arguments of this Value using the provided Allocator (`alloc`). /// This will pull All values from `_set_args` and should be used with `Multi` Set Behavior. - pub fn getAll(self: *const @This(), alloc: mem.Allocator) ![]ChildT { + pub fn getAllAlloc(self: *const @This(), alloc: mem.Allocator) ![]ChildT { if (!self.is_set) { if (self.default_val) |def_val| { var val = try alloc.alloc(ChildT, 1); @@ -366,6 +366,12 @@ pub fn Typed(comptime SetT: type, comptime config: Config) type { return vals; } + /// Get All Parsed and Validated Arguments of this Value. + /// This will pull All values from `_set_args` and should be used with `Multi` Set Behavior. + pub fn getAll(self: *const @This()) ![]ChildT { + return self.getAllAlloc(self._alloc orelse return error.ValueNotInitialized); + } + /// Initialize this Value with the provided Allocator (`alloc`). pub fn init(self: *const @This(), alloc: mem.Allocator) @This() { var val = self.*; @@ -641,6 +647,35 @@ pub fn Custom(comptime config: Config) type { }; } + /// Get All of the Parsed and Validated values of the inner Typed Value as a Slice of the specified Type (`T`). + pub fn getAllAs(self: *const @This(), comptime T: type) ![]T { + return switch (meta.activeTag(self.*.generic)) { + inline else => |tag| { + const typed_val = @field(self.*.generic, @tagName(tag)); + return + if (@TypeOf(typed_val).ChildT == T) try typed_val.getAll() + else if ( + @typeInfo(T) == .Enum or ( + @typeInfo(T) == .Optional and + @typeInfo(@typeInfo(T).Optional.child) == .Enum + ) + ) { + const ValT = @typeInfo(@TypeOf(try typed_val.get())); + switch (ValT) { + .Int => { + const vals = try typed_val.getAll(); + var vals_list = std.ArrayList(T).init(self.allocator().?); + for (vals) |val| try vals_list.append(@enumFromInt(val)); + return try vals_list.toOwnedSlice(); + }, + inline else => return error.RequestedTypeMismatch, + } + } + else error.RequestedTypeMismatch; + }, + }; + } + /// Set the inner Typed Value if the provided Argument (`arg`) can be Parsed and Validated. pub fn set(self: *const @This(), arg: []const u8) !void { switch (meta.activeTag(self.*.generic)) { diff --git a/src/utils.zig b/src/utils.zig index 6db559d..9b9abad 100644 --- a/src/utils.zig +++ b/src/utils.zig @@ -54,7 +54,7 @@ fn displayValInfo( switch (meta.activeTag(val.generic)) { .string => { - const str_vals = val.generic.string.getAll(alloc) catch noVal: { + const str_vals = val.generic.string.getAllAlloc(alloc) catch noVal: { const no_val = alloc.dupe([]const u8, &.{ "" }) catch @panic("OOM"); break :noVal no_val; }; @@ -71,7 +71,7 @@ fn displayValInfo( const tag_self = @field(val.generic, @tagName(tag)); if (tag_self.set_behavior == .Multi) { const raw_data: ?[]const @TypeOf(tag_self).ChildT = rawData: { - if (tag_self.getAll(alloc) catch null) |data| break :rawData data; + if (tag_self.getAllAlloc(alloc) catch null) |data| break :rawData data; const data: ?@TypeOf(tag_self).ChildT = tag_self.get() catch null; if (data) |_data| { var data_slice = alloc.alloc(@TypeOf(tag_self).ChildT, 1) catch @panic("OOM");