Adds support for value-passing via =
.
This commit is contained in:
parent
8a505b6930
commit
a5456dbf10
|
@ -7,6 +7,7 @@ Simple-to-use argument parser with struct-based config
|
||||||
- Everything after the first `--` is assumed to be a positional argument
|
- Everything after the first `--` is assumed to be a positional argument
|
||||||
- A single `-` is interpreted as a positional argument which can be used as the stdin/stdout file placeholder
|
- A single `-` is interpreted as a positional argument which can be used as the stdin/stdout file placeholder
|
||||||
- Short options with no argument can be combined into a single argument: `-dfe`
|
- Short options with no argument can be combined into a single argument: `-dfe`
|
||||||
|
- Long options can use either `--option=value` or `--option value` syntax
|
||||||
- Integrated support for primitive types:
|
- Integrated support for primitive types:
|
||||||
- All integer types (signed & unsigned)
|
- All integer types (signed & unsigned)
|
||||||
- Floating point types
|
- Floating point types
|
||||||
|
|
39
args.zig
39
args.zig
|
@ -20,16 +20,33 @@ pub fn parse(comptime Spec: type, args: *std.process.ArgIterator, allocator: *st
|
||||||
// double hyphen is considered 'everything from here now is positional'
|
// double hyphen is considered 'everything from here now is positional'
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Pair = struct {
|
||||||
|
name: []const u8,
|
||||||
|
value: ?[]const u8,
|
||||||
|
};
|
||||||
|
|
||||||
|
const pair = if (std.mem.indexOf(u8, item, "=")) |index|
|
||||||
|
Pair{
|
||||||
|
.name = item[2..index],
|
||||||
|
.value = item[index + 1 ..],
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Pair{
|
||||||
|
.name = item[2..],
|
||||||
|
.value = null,
|
||||||
|
};
|
||||||
|
|
||||||
var found = false;
|
var found = false;
|
||||||
inline for (std.meta.fields(Spec)) |fld| {
|
inline for (std.meta.fields(Spec)) |fld| {
|
||||||
if (std.mem.eql(u8, item[2..], fld.name)) {
|
if (std.mem.eql(u8, pair.name, fld.name)) {
|
||||||
try parseOption(Spec, &result, args, fld.field_type, fld.name);
|
try parseOption(Spec, &result, args, fld.field_type, fld.name, pair.value);
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!found) {
|
if (!found) {
|
||||||
try std.io.getStdErr().outStream().stream.print("Unknown command line option: {}\n", .{item});
|
try std.io.getStdErr().outStream().stream.print("Unknown command line option: {}\n", .{pair.name});
|
||||||
return error.EncounteredUnknownArgument;
|
return error.EncounteredUnknownArgument;
|
||||||
}
|
}
|
||||||
} else if (std.mem.startsWith(u8, item, "-")) {
|
} else if (std.mem.startsWith(u8, item, "-")) {
|
||||||
|
@ -52,7 +69,7 @@ pub fn parse(comptime Spec: type, args: *std.process.ArgIterator, allocator: *st
|
||||||
return error.EncounteredUnexpectedArgument;
|
return error.EncounteredUnexpectedArgument;
|
||||||
}
|
}
|
||||||
|
|
||||||
try parseOption(Spec, &result, args, real_fld.field_type, real_fld.name);
|
try parseOption(Spec, &result, args, real_fld.field_type, real_fld.name, null);
|
||||||
|
|
||||||
found = true;
|
found = true;
|
||||||
}
|
}
|
||||||
|
@ -135,9 +152,19 @@ fn convertArgumentValue(comptime T: type, textInput: []const u8) !T {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parseOption(comptime Spec: type, _result: *ParseArgsResult(Spec), _args: *std.process.ArgIterator, comptime field_type: type, comptime name: []const u8) !void {
|
fn parseOption(
|
||||||
|
comptime Spec: type,
|
||||||
|
_result: *ParseArgsResult(Spec),
|
||||||
|
_args: *std.process.ArgIterator,
|
||||||
|
comptime field_type: type,
|
||||||
|
comptime name: []const u8,
|
||||||
|
value: ?[]const u8,
|
||||||
|
) !void {
|
||||||
@field(_result.options, name) = if (requiresArg(field_type)) blk: {
|
@field(_result.options, name) = if (requiresArg(field_type)) blk: {
|
||||||
const argval = try (_args.next(&_result.arena.allocator) orelse {
|
const argval = if (value) |val|
|
||||||
|
val
|
||||||
|
else
|
||||||
|
try (_args.next(&_result.arena.allocator) orelse {
|
||||||
try std.io.getStdErr().outStream().stream.print(
|
try std.io.getStdErr().outStream().stream.print(
|
||||||
"Missing argument for {}.\n",
|
"Missing argument for {}.\n",
|
||||||
.{name},
|
.{name},
|
||||||
|
|
Loading…
Reference in New Issue
Block a user