Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

required_unless, required_unless_one, and required_unless_all for ArgGroup #1801

Open
AuroransSolis opened this issue Apr 9, 2020 · 3 comments
Labels
A-validators Area: ArgMatches validation logi C-enhancement Category: Raise on the bar on expectations S-waiting-on-mentor Status: Needs elaboration on the details before doing a 'Call for participation'

Comments

@AuroransSolis
Copy link

AuroransSolis commented Apr 9, 2020

Describe your use case

The issue this aims to solve is the lack of required_unless, required_unless_one, and required_unless_all for ArgGroup. For example, one might have the following:

let app = App::new("example")
    .arg(Arg::with_name("foo-user")
        .takes_value(true)
        .long("foo-user"))
    .arg(Arg::with_name("foo-user-file")
        .takes_value(true)
        .long("foo-user-file"))
    .group(ArgGroup::with_name("foo-username")
        .args(&["foo-user", "foo-user-file"])
        .multiple(false)
        .requires("foo-password"))
    .arg(Arg::with_name("foo-pass")
        .takes_value(true)
        .long("foo-pass"))
    .arg(Arg::with_name("foo-pass-file")
        .takes_value(true)
        .long("foo-pass-file"))
    .group(ArgGroup::with_name("foo-password")
        .args(&["foo-pass", "foo-pass-file"])
        .multiple(false))
    .group(ArgGroup::with_name("foo-creds")
        .args(&["foo-username", "foo-password"])
        .requires_all(&["foo-username", "foo-password"])
        .multiple(true)
        .required_unless("bar-creds"))
    .arg(Arg::with_name("bar-user")
        .takes_value(true)
        .requires("bar-password")
        .long("bar-user"))
    .arg(Arg::with_name("bar-user-file")
        .takes_value(true)
        .requires("bar-password")
        .long("bar-user-file"))
    .group(ArgGroup::with_name("bar-username")
        .args(&["bar-user", "bar-user-file"])
        .multiple(false))
    .arg(Arg::with_name("bar-pass")
        .takes_value(true)
        .long("bar-pass"))
    .arg(Arg::with_name("bar-pass-file")
        .takes_value(true)
        .long("bar-pass-file"))
    .group(ArgGroup::with_name("bar-password")
        .args(&["bar-pass", "bar-pass-file"])
        .multiple(false))
    .group(ArgGroup::with_name("bar-creds")
        .args(&["bar-username", "bar-password"])
        .multiple(true))
    .arg(Arg::with_name("bar-fallback-to-foo")
        .takes_value(false)
        .requires_all(&["foo-creds", "bar-creds"]));

One might imagine a different situation where required_unless_one or required_unless_all might be of use as well, but the only short example I could come up with is one demonstrating the use of required_unless. This reduces the number of lines required to express certain requirements by moving a required_unless, required_unless_one, or required_unless_all method from each argument in the group to a single one on the group itself. This also makes requirements for group arguments more clear and maintainable, as they're located in a single spot instead of on each group argument.

Alternatives

It may be possible in some situations to use required_unless, required_unless_one, or required_unless_all on the arguments in the group one might otherwise apply to the group itself, but this would be at least one line per argument, possibly more if the slices for required_unless_one or required_unless_all are particularly long.

@pksunkara pksunkara added C: arg groups E-easy Call for participation: Experience needed to fix: Easy / not much labels Apr 9, 2020
@pksunkara pksunkara added this to the 3.1 milestone Apr 9, 2020
@j-delaney
Copy link

I'm happy to take a shot at this if that's okay!

@Dylan-DPC-zz
Copy link

Go ahead. Thanks

@pksunkara
Copy link
Member

Better way to fix this would be implementing the following way

factoring out most of Arg and ArgGroup into new ArgBase struct to avoid code duplication

@epage epage added A-builder Area: Builder API A-validators Area: ArgMatches validation logi C-enhancement Category: Raise on the bar on expectations S-waiting-on-mentor Status: Needs elaboration on the details before doing a 'Call for participation' and removed C: arg groups A-builder Area: Builder API E-easy Call for participation: Experience needed to fix: Easy / not much labels Dec 8, 2021
@epage epage removed this from the 3.1 milestone Dec 9, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-validators Area: ArgMatches validation logi C-enhancement Category: Raise on the bar on expectations S-waiting-on-mentor Status: Needs elaboration on the details before doing a 'Call for participation'
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants