Clap derive required flags or options that are exclusive to each other

Hello,

I'm building a tool that uses the clap crate. I want to have a few options and/or flags that are required, but exclusive to each other (only one of a grouping can be used).

For example, my application's signiture is this:

USAGE:
    lisa [OPTIONS] --input <INPUT> --output <OUTPUT> --list <LIST> --foo <FOO> --bar <BAR>

but I want it to be this:

USAGE:
    lisa [OPTIONS] --input <INPUT> --output <OUTPUT> [--list <LIST>, --foo <FOO>, --bar <BAR>]

Intuitively I thought an enum would do the trick but that didn't work.

I've done this kind of thing before but with the builder API, never with the derive API. When using the builder API I would group the options together then do something like this:

        .group(ArgGroup::with_name("extraction_types")
            .args(&["all", "verse"])
            .multiple(false)
            .required(true),

The above is the pattern I'm after.

The source code I'm trying to fit this into can be found here.

Thanks for any help!

P.S.
I know I can mix derive and builder APIs but that seems messy. I'm hoping there's a solution only using the derive api if it is possible.

1 Like

I think this clap/README.md at v3.1.18 · clap-rs/clap · GitHub has an example.

Look in the source code where you find something like this:

/// some regular input
    #[clap(group = "input")]
    input_file: Option<String>,
1 Like

Thank you @manfredlotz! I had looked in the clap reference and didn't see it. Glad it was in the tutorial.

@JoelMon I think it should be added to the clap derive reference. Perhaps I should open an issue in the clap github repository.

Also the examples are a more complicated then needs be. In the example they use the build pattern on top of the struct when in reality anyone searching for derive patterns would want to use the derive API on the fields them selves like I have done below.

#[derive(Parser)]
#[clap(author, version, about, long_about = None)]
struct Cli {
    /// The PO csv file to be used
    #[clap(short, long)]
    input: PathBuf,
    /// The destination directory where the processed POs will be saved
    #[clap(short, long)]
    output: PathBuf,
    /// The text file that contains all of the store numbers to be processed
    #[clap(short, long)]
    list: PathBuf,
    /// Print all RFIDs including items marked with a '$'
    #[clap(short = 'a', long = "print-all", conflicts_with = "report")]
    printall: bool,
    /// Produce a report of selected PO
    #[clap(short, long, conflicts_with = "printall")]
    report: bool,
}

I'm going to fix that on their examples soon. I'm guessing the examples were made before the API was finished.

Speaking of simplification, conflicts_with is bi-directional according to it's documentation, and thus should be sufficient to use only on either item, and is not needed for both...

I am not 100% sure so please dont's take it for granted, but i believe that the buidler excerpt for the group was needed for code to properly generate help strings for the exclusive arguments (e.g. to show --A | --B in help instead of standalone arguments next to each other)

Yeah, you are right

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.