Structopt: Argument groups

Created on 4 Sep 2017  Â·  7Comments  Â·  Source: TeXitoi/structopt

Is there a plan to add argument groups / mutually exclusive flags and or options? After a little searching I either couldn't see how to achieve them, or came to the conclusion that I would need to use clap directly.

For example,

Allow:
command --arg1
command --arg2
command --arg1 [name]

But not allow:
command --arg1 [name] --arg2

Also to combine the mutually exclusiveness these with subcommands,

Allow:
command subcommand --subarg1

But not allow:
command --arg1 subcommand --subarg1
command --arg1 [name] --arg2 subcommand --subarg1

(edit, added examples)

Thanks.

question

Most helpful comment

All 7 comments

Transcription of https://docs.rs/clap/2.26.0/clap/struct.Arg.html#method.conflicts_with

extern crate structopt;
#[macro_use]
extern crate structopt_derive;

use structopt::StructOpt;

#[derive(StructOpt, Debug)]
struct Opt {
    #[structopt(long = "config", conflicts_with = "debug")]
    cfg: Option<String>,
    #[structopt(long = "debug")]
    debug: bool,
}

fn main() {
    let opt = Opt::from_args();
    println!("{:?}", opt);
}
cargo run -- --debug --config file.conf
    Finished dev [unoptimized + debuginfo] target(s) in 0.0 secs
     Running `/home/gupinot/dev/test-rs/target/debug/test-rs --debug --config file.conf`
error: The argument '--config <cfg>' cannot be used with '--debug'

USAGE:
    test-rs --debug

For more information try --help

From the doc at https://docs.rs/structopt-derive/0.1.0/structopt_derive/

As with the struct attributes, every method of clap::Arg in the form of fn function_name(self, &str) can be used through specifying it as an attribute.

Does it answer your question? Do you have an idea of what we can do to help find this information?

It does answer my question for the most part - my bad for not reading thoroughly. As for clarity, I think it's clear enough.

So I have the ability to specify conflicting arguments per app/subcommand.
What about conflicts with for a subcommand? (require the inability to specify a particular argument and a subcommand)

I can't find the feature in clap. Do you know how to do that with clap? If that's not possible with clap, that's not possible with structopt.

Close, but not exactly the same issue: Can I require that exactly one argument of two conflicting arguments is provided?

This is possible in clap by making the argument group required: https://kbknapp.github.io/clap-rs/clap/struct.ArgGroup.html

https://github.com/TeXitoi/structopt/blob/master/examples/group.rs

This is unsatisfactory as it doesn't allow for convenient parsing of enums. To quote the given example:

struct Opt {
    /// Set a custom HTTP verb
    #[structopt(long, group = "verb")]
    method: Option<String>,
    /// HTTP GET
    #[structopt(long, group = "verb")]
    get: bool,
    /// HTTP HEAD
    #[structopt(long, group = "verb")]
    head: bool,
    /// HTTP POST
    #[structopt(long, group = "verb")]
    post: bool,
    /// HTTP PUT
    #[structopt(long, group = "verb")]
    put: bool,
    /// HTTP DELETE
    #[structopt(long, group = "verb")]
    delete: bool,
}

To get something like

enum Method {
  Get,
  Head,
  Post,
  Put,
  Delete,
}

The user has to do something like

if opts.get { return Method::Get }
if opts.head { return Method::Post }
…
panic!("shouldn't happen or structopt failed to ensure some option was set");

which gets really annoying super fast.

A more appropriate pattern for this use case is https://github.com/TeXitoi/structopt/blob/master/examples/enum_in_args.rs but that's a different interface.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

SirWindfield picture SirWindfield  Â·  3Comments

gnzlbg picture gnzlbg  Â·  5Comments

TedDriggs picture TedDriggs  Â·  6Comments

bb010g picture bb010g  Â·  9Comments

liamdawson picture liamdawson  Â·  5Comments