Skip to content
This repository has been archived by the owner on Jan 1, 2022. It is now read-only.

Using index_of()/indices_of() with optional arguments that take optional values #183

Open
2 tasks done
epage opened this issue Dec 6, 2021 · 0 comments
Open
2 tasks done

Comments

@epage
Copy link
Owner

epage commented Dec 6, 2021

Issue by cptpcrd
Saturday Mar 20, 2021 at 17:21 GMT
Originally opened as clap-rs/clap#2419


Please complete the following tasks

  • I have searched the discussions
  • I have searched the existing issues

Describe your use case

I have multiple optional arguments with optional values. If several of them were specified without passing a value, I want to determine the indices of the arguments so I can find out which one was specified first. However, it seems that this is one of the few cases where Arg::index_of()/Arg::indices_of() doesn't work.

A simple example can be found below.

Describe the solution you'd like

Ideally, Arg::index_of() would work for arguments with optional values.

Alternatives, if applicable

Perhaps a new method, say Args::index_of_opt() (which would return the index of the flag like -a or --all`, instead of the value) could be added?

Additional Context

I'm using structopt, but I've translated this to clap code.

Example with clap 2.33:

fn main() {
    use clap::{Arg, App};
    
    let app = App::new("Basic Test")
        .arg(Arg::with_name("abc")
            .short("a")
            .long("abc")
            .takes_value(true)
            .multiple(false)
            .min_values(0)
            .max_values(1));

    // I can get the index in all of these cases (because clap returns the index of the value)

    let matches = app.clone().get_matches_from(&["", "-a1"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "--abc=1"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "-a", "1"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "--abc", "1"]);
    println!("{:?}", matches.index_of("abc"));

    // But I can't get the index in these cases (which is when I really need it!)

    let matches = app.clone().get_matches_from(&["", "-a"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "--abc"]);
    println!("{:?}", matches.index_of("abc"));
}

This produces the following output:

Some(2)
Some(2)
Some(2)
Some(2)
None
None
Updated for clap 3 (produces the same output as the above version when run against the latest master):
fn main() {
    use clap::{Arg, App};
    
    let app = App::new("Basic Test")
        .arg(Arg::new("abc")
            .short('a')
            .long("abc")
            .takes_value(true)
            .multiple(false)
            .min_values(0)
            .max_values(1));

    // I can get the index in all of these cases (because clap returns the index of the value)

    let matches = app.clone().get_matches_from(&["", "-a1"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "--abc=1"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "-a", "1"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "--abc", "1"]);
    println!("{:?}", matches.index_of("abc"));

    // But I can't get the index in these cases (which is when I really need it!)

    let matches = app.clone().get_matches_from(&["", "-a"]);
    println!("{:?}", matches.index_of("abc"));

    let matches = app.clone().get_matches_from(&["", "--abc"]);
    println!("{:?}", matches.index_of("abc"));
}
@epage epage added this to the 3.1 milestone Dec 6, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

1 participant