zig-args icon indicating copy to clipboard operation
zig-args copied to clipboard

support for slice and/or array types - multiple values on one option

Open ktiy opened this issue 4 years ago • 2 comments
trafficstars

not sure how to word this one; it would be cool to have support for slice and/or array types for multiple values on one option

const options = try argsParser.parse(struct {
    outputs: ?[][]const u8 = null, // slice, "--outputs output1 output2 etc."
    resolution: ?[2]u32 = null, // array, "--resolution 1920 1080"

    pub const shorthands = .{
        .r = "resolution",
        .o = "outputs",
    };
}, &args, argsAllocator);

im not sure how difficult this would be to implement though ^_^;

ktiy avatar Nov 26 '20 05:11 ktiy

Unlimited slice lengths are kinda weird, but what i wanted to support anyways at a point are custom types that have a parseCliOption function, so you can do this:

const options = try argsParser.parse(struct {
    outputs: ?OutputList = null, // slice, "--outputs output1,output2,output3 etc."
    resolution: ?Size = null, // array, "--resolution 1920x1080"

    pub const shorthands = .{
        .r = "resolution",
        .o = "outputs",
    };
}, &args, argsAllocator);

im not sure how difficult this would be to implement though ^_^;

The problem is that it's not unique anymore:

--outputs a b c d

Which of a, b, c, d is a positional argument, which one belongs to outputs?

One option would be to allow this:

--outputs a b c -- d

Where -- terminates the list.

The stuff in the first section is definitly planned (custom types), but let me think a bit about the second one (variadic length)

ikskuh avatar Nov 26 '20 07:11 ikskuh

Here's a decision for this:

We use a custom "list" type from args:

var cli = try args.parse(struct {
    item: args.Repeatable(i32) = .{}, // must be default constructible
    list: args.List(i32) = .{}, 
}, …);

const items: []const i32 = cli.options.item.get();
std.debug.print("items={any}\n", .{ items });

const list: []const i32 = cli.options.list.get();
std.debug.print("list={any}\n", .{ list });

which can be invoked like this:

[user@host] ~ $ ./demo --item 1 --item 2 --item 3 --list 4 5 6 7 -- --item 8
items={ 1, 2, 3, 8 }
list={ 4, 5, 6, 7 }

--item can be specified more than once, --list can only be specified once and must be terminated with --

ikskuh avatar Mar 20 '24 10:03 ikskuh