ikskuh / zig-args

Simple-to-use argument parser with struct-based config
MIT License
243 stars 27 forks source link

Mutually exclusive options #15

Open yohannd1 opened 3 years ago

yohannd1 commented 3 years ago

Since https://github.com/MasterQ32/zig-args/issues/3 is already using inner structs to express subcommands, I was thinking of something like:

const expect = @import("std").testing.expect;
const ap = @import("args.zig");

_ = try ap.parse(struct {
    // Some restrictions for this argument:
    //
    // * On the application help (if it gets implemented), the name `case_sensitivity` shouldn't be seen - only its
    // inner options, maybe grouped under some kind of section.
    //
    // * Shorthands for this argument cannot be declared on the `shorthands` constant of this struct and instead
    // should be declared on this mutually exclusive group's type (CaseSensitivity).
    //
    // Also, this syntax looks a little bit flicky; I'm not sure if it is the best way to do this.
    case_sensitivity: ap.MutuallyExclusive(CaseSensitivity) = ap.MutuallyExclusive(CaseSensitivity){ .value = .@"case-sensitive" },

    pub const shorthands = .{
        .s = "case_sensitivity", // as said, this doesn't make sense and shouldn't work.
    };
}, &args, &allocator);

// The type could be either a tagged union (`union(enum)`) - if any of the options accepted args - or an enum - if
// no options accepted args. - In this case, I'm using an enum because `case-sensitive` and `case-insensitive` just
// need to be enabled, and don't need any extra configuration.
const CaseSensitivity = enum {
    @"case-sensitive",
    @"case-insensitive",

    // We can declare the shorthands for this mutually exclusive group here. They may not be repeated on the parent
    // type or by other mutually exclusive groups.
    pub const shorthands = .{
        .S = "case-sensitive",
        .I = "case-insensitive",
    };
};