fix(parser): Allow multiple_occurrecnes with positional args

This unblocks
- Defining repeated tuples in positional arguments
- Potentially using this in #1772

Fixes #2784
This commit is contained in:
Ed Page 2021-10-04 12:09:54 -05:00
parent 236cf584cf
commit 8e780e364d
3 changed files with 61 additions and 20 deletions

View file

@ -35,15 +35,6 @@ pub(crate) fn assert_arg(arg: &Arg) {
);
}
// Positionals should not have multiple_occurrences
if arg.is_positional() {
assert!(
!arg.is_set(ArgSettings::MultipleOccurrences),
"Argument '{}' is a positional argument and can't be set as multiple occurrences",
arg.name
);
}
if arg.is_set(ArgSettings::Required) {
assert!(
arg.default_vals.is_empty(),

View file

@ -1319,3 +1319,64 @@ fn number_of_values_preferred_over_value_names() {
["val1", "val2", "val3", "val4"]
);
}
#[test]
fn values_per_occurrence_named() {
let mut a = App::new("test").arg(
Arg::new("pos")
.long("pos")
.number_of_values(2)
.multiple_occurrences(true),
);
let m = a.try_get_matches_from_mut(vec!["myprog", "--pos", "val1", "val2"]);
let m = match m {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
assert_eq!(
m.values_of("pos").unwrap().collect::<Vec<_>>(),
["val1", "val2"]
);
let m = a.try_get_matches_from_mut(vec![
"myprog", "--pos", "val1", "val2", "--pos", "val3", "val4",
]);
let m = match m {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
assert_eq!(
m.values_of("pos").unwrap().collect::<Vec<_>>(),
["val1", "val2", "val3", "val4"]
);
}
#[test]
fn values_per_occurrence_positional() {
let mut a = App::new("test").arg(
Arg::new("pos")
.number_of_values(2)
.multiple_occurrences(true),
);
let m = a.try_get_matches_from_mut(vec!["myprog", "val1", "val2"]);
let m = match m {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
assert_eq!(
m.values_of("pos").unwrap().collect::<Vec<_>>(),
["val1", "val2"]
);
let m = a.try_get_matches_from_mut(vec!["myprog", "val1", "val2", "val3", "val4"]);
let m = match m {
Ok(m) => m,
Err(err) => panic!("{}", err),
};
assert_eq!(
m.values_of("pos").unwrap().collect::<Vec<_>>(),
["val1", "val2", "val3", "val4"]
);
}

View file

@ -296,14 +296,3 @@ fn positional_arg_with_short() {
.arg(Arg::new("arg").index(1).short('a'))
.try_get_matches();
}
#[cfg(debug_assertions)]
#[test]
#[should_panic = "Argument 'arg' is a positional argument and can't be set as multiple occurrences"]
fn positional_arg_with_multiple_occurrences() {
use clap::{App, Arg};
let _ = App::new("test")
.arg(Arg::new("arg").multiple_occurrences(true))
.try_get_matches();
}