From 8e780e364d968476e11ce29dfb17fc00846febd8 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Mon, 4 Oct 2021 12:09:54 -0500 Subject: [PATCH] fix(parser): Allow multiple_occurrecnes with positional args This unblocks - Defining repeated tuples in positional arguments - Potentially using this in #1772 Fixes #2784 --- src/build/arg/debug_asserts.rs | 9 ----- tests/multiple_values.rs | 61 ++++++++++++++++++++++++++++++++++ tests/positionals.rs | 11 ------ 3 files changed, 61 insertions(+), 20 deletions(-) diff --git a/src/build/arg/debug_asserts.rs b/src/build/arg/debug_asserts.rs index 9ef5bc81..1b9ed912 100644 --- a/src/build/arg/debug_asserts.rs +++ b/src/build/arg/debug_asserts.rs @@ -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(), diff --git a/tests/multiple_values.rs b/tests/multiple_values.rs index abd7bc34..d8584bc6 100644 --- a/tests/multiple_values.rs +++ b/tests/multiple_values.rs @@ -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::>(), + ["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::>(), + ["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::>(), + ["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::>(), + ["val1", "val2", "val3", "val4"] + ); +} diff --git a/tests/positionals.rs b/tests/positionals.rs index d085b316..96f66ad6 100644 --- a/tests/positionals.rs +++ b/tests/positionals.rs @@ -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(); -}