Skip to content

Commit

Permalink
Enabled Analysis f/ Multi Values & Option
Browse files Browse the repository at this point in the history
- Added the `getAllAs()` method for `Value.Custom` to easily get multi-Values (and Options) during analysis.
- Added the `getAllAlloc()` method for `Value.Typed` to support easier function wrapping with the original `getAll()`.
  • Loading branch information
00JCIV00 committed Jul 24, 2024
1 parent 86dd10d commit a1ffd74
Show file tree
Hide file tree
Showing 3 changed files with 45 additions and 4 deletions.
6 changes: 6 additions & 0 deletions examples/covademo.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
//}
Expand Down
39 changes: 37 additions & 2 deletions src/Value.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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.*;
Expand Down Expand Up @@ -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)) {
Expand Down
4 changes: 2 additions & 2 deletions src/utils.zig
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
Expand All @@ -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");
Expand Down

0 comments on commit a1ffd74

Please sign in to comment.