This commit is contained in:
Lyssieth 2024-11-29 19:36:56 +02:00
parent 6a6bffaa3b
commit c9a3b90160
Signed by untrusted user who does not match committer: lyssieth
GPG key ID: 200268854934CFAB
4 changed files with 52 additions and 3 deletions

View file

@ -167,6 +167,7 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
}
const fie = &@field(result, field.name);
const fieldType = @typeInfo(@TypeOf(fie.*.value));
const extra: Extra = fie.*.extra;
switch (extra) {
@ -242,8 +243,6 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
return error.InvalidFlag;
}
const fieldType = @typeInfo(@TypeOf(fie.*.value));
switch (fieldType) {
.Optional => |_| {
log.debug("flag `{s}` is optional, and we couldn't find a value for it, so leaving as default value", .{f.name});
@ -358,6 +357,17 @@ fn initFromParsed(comptime T: type, allocator: Allocator, flags: []Arg) !T {
return error.InvalidPositional;
}
} else {
switch (fieldType) {
.Optional => {
if (!builtin.is_test) {
log.warn("could not find positional argument for `{s}`, using default value", .{field.name});
}
comptime continue;
},
else => {},
}
if (builtin.is_test) {
// early return to not pollute the stderr
return error.NoArgumentFound;
@ -529,6 +539,33 @@ test "missing positional because empty arg" {
try t.expectError(error.NoArgumentFound, result);
}
test "positional has default value so we get a free pass" {
const args = try t.allocator.alloc([]const u8, 1);
defer t.allocator.free(args);
args[0] = "--toggle";
const Demo = struct {
allocator: Allocator,
positional: Marker(?u8) = .{
.value = 255,
.extra = .{
.Positional = .{},
},
.parse = parsers.numNullable(u8),
},
fn deinit(self: *@This()) void {
self.* = undefined;
}
};
const result = try parseArgsFromSlice(Demo, t.allocator, args);
try t.expectEqual(255, result.positional.value);
}
test "parse fn (positional)" {
const args = try t.allocator.alloc([]const u8, 3);
defer t.allocator.free(args);

View file

@ -3,7 +3,7 @@ const std = @import("std");
pub fn num(comptime T: type) *const fn (value: []const u8) anyerror!T {
const container = struct {
fn func(value: []const u8) anyerror!T {
return std.fmt.parseInt(T, value, 10);
return try std.fmt.parseInt(T, value, 10);
}
};

View file

@ -0,0 +1,11 @@
const std = @import("std");
pub fn numNullable(comptime T: type) *const fn (value: []const u8) anyerror!?T {
const container = struct {
fn func(value: []const u8) anyerror!?T {
return try std.fmt.parseInt(T, value, 10);
}
};
return &container.func;
}

View file

@ -8,6 +8,7 @@ pub fn ParseSignature(comptime T: type) type {
}
pub const num = @import("./num.zig").num;
pub const numNullable = @import("./numNullable.zig").numNullable;
pub const boolean = @import("./boolean.zig").boolean;
pub const enumLiteral = @import("./enumLiteral.zig").enumLiteral;