-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
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
Indices #1196
Conversation
/// assert_eq!(m.index_of("option"), Some(2)); | ||
/// ``` | ||
/// [`ArgMatches`]: ./struct.ArgMatches.html | ||
/// [delimiter]: ./struct.Arg.html#method.value_delimiter |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting! I didn't think of the argv vs clap index, and it does indeed seem like I'd want the clap index. Great find. :-)
Just rebased on the current master (reason for the rebuild) |
Adds the abiltiy to query the matches struct for the indices of values or flags. The index is similar to that of an argv index, but not exactly a 1:1. For flags (i.e. those arguments which don't have an associated value), indices refer to occurrence of the switch, such as `-f`, or `--flag`. However, for options the indices refer to the *values* `-o val` would therefore not represent two distinct indices, only the index for `val` would be recorded. This is by design. Besides the flag/option descrepancy, the primary difference between an argv index and clap index, is that clap continues counting once all arguments have properly seperated, whereas an argv index does not. The examples should clear this up. *NOTE:* If an argument is allowed multiple times, this method will only give the *first* index. The argv indices are listed in the comments below. See how they correspond to the clap indices. Note that if it's not listed in a clap index, this is becuase it's not saved in in an `ArgMatches` struct for querying. ```rust let m = App::new("myapp") .arg(Arg::with_name("flag") .short("f")) .arg(Arg::with_name("option") .short("o") .takes_value(true)) .get_matches_from(vec!["myapp", "-f", "-o", "val"]); // ARGV idices: ^0 ^1 ^2 ^3 // clap idices: ^1 ^3 assert_eq!(m.index_of("flag"), Some(1)); assert_eq!(m.index_of("option"), Some(3)); ``` Now notice, if we use one of the other styles of options: ```rust let m = App::new("myapp") .arg(Arg::with_name("flag") .short("f")) .arg(Arg::with_name("option") .short("o") .takes_value(true)) .get_matches_from(vec!["myapp", "-f", "-o=val"]); // ARGV idices: ^0 ^1 ^2 // clap idices: ^1 ^3 assert_eq!(m.index_of("flag"), Some(1)); assert_eq!(m.index_of("option"), Some(3)); ``` Things become much more complicated, or clear if we look at a more complex combination of flags. Let's also throw in the final option style for good measure. ```rust let m = App::new("myapp") .arg(Arg::with_name("flag") .short("f")) .arg(Arg::with_name("flag2") .short("F")) .arg(Arg::with_name("flag3") .short("z")) .arg(Arg::with_name("option") .short("o") .takes_value(true)) .get_matches_from(vec!["myapp", "-fzF", "-oval"]); // ARGV idices: ^0 ^1 ^2 // clap idices: ^1,2,3 ^5 // // clap sees the above as 'myapp -f -z -F -o val' // ^0 ^1 ^2 ^3 ^4 ^5 assert_eq!(m.index_of("flag"), Some(1)); assert_eq!(m.index_of("flag2"), Some(3)); assert_eq!(m.index_of("flag3"), Some(2)); assert_eq!(m.index_of("option"), Some(5)); ``` One final combination of flags/options to see how they combine: ```rust let m = App::new("myapp") .arg(Arg::with_name("flag") .short("f")) .arg(Arg::with_name("flag2") .short("F")) .arg(Arg::with_name("flag3") .short("z")) .arg(Arg::with_name("option") .short("o") .takes_value(true) .multiple(true)) .get_matches_from(vec!["myapp", "-fzFoval"]); // ARGV idices: ^0 ^1 // clap idices: ^1,2,3^5 // // clap sees the above as 'myapp -f -z -F -o val' // ^0 ^1 ^2 ^3 ^4 ^5 assert_eq!(m.index_of("flag"), Some(1)); assert_eq!(m.index_of("flag2"), Some(3)); assert_eq!(m.index_of("flag3"), Some(2)); assert_eq!(m.index_of("option"), Some(5)); ``` The last part to mention is when values are sent in multiple groups with a [delimiter]. ```rust let m = App::new("myapp") .arg(Arg::with_name("option") .short("o") .takes_value(true) .multiple(true)) .get_matches_from(vec!["myapp", "-o=val1,val2,val3"]); // ARGV idices: ^0 ^1 // clap idices: ^2 ^3 ^4 // // clap sees the above as 'myapp -o val1 val2 val3' // ^0 ^1 ^2 ^3 ^4 assert_eq!(m.index_of("option"), Some(2)); ```
Should be good for a merge now 🎉 |
@BurntSushi if you wouldn't mind checking out the examples/tests and making sure this meets your requirements. If it does I'll put out v2.31.0, otherwise I can still make edits before the version goes out. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! This looks perfect!
Adds the scaffolding to add index querying methods to
ArgMatches
, namelyindex_of
andindices_of
This change is