I want to build a CLI in Rust, using clap, which can accept some number of positional arguments with a set number of values each, and a final argument accepting whatever positional values were left over. For example, ./app a b c with a positional argument accepting 2 values, and a positional argument accepting leftovers, would assign a b to the first arg, and c to the second. I'm able to do this with a positional argument that accepts a single value:
let cmd = Command::new("main")
.arg(Arg::new("ONE").action(ArgAction::Set).num_args(1))
.arg(Arg::new("TWO").action(ArgAction::Append));
let matches = cmd.get_matches_from(&["bin","a","b","c"]);
assert_eq!(matches.get_many::<String>("ONE").unwrap().collect::<Vec<_>>(), &["a"]);
assert_eq!(matches.get_many::<String>("TWO").unwrap().collect::<Vec<_>>(), &["b","c"]);
But if I try to have the first arg accept two values like this:
let cmd = Command::new("main")
.arg(Arg::new("ONE").action(ArgAction::Set).num_args(2))
.arg(Arg::new("TWO").action(ArgAction::Append));
let matches = cmd.get_matches_from(&["bin","a","b","c"]);
assert_eq!(matches.get_many::<String>("ONE").unwrap().collect::<Vec<_>>(), &["a","b"]);
assert_eq!(matches.get_many::<String>("TWO").unwrap().collect::<Vec<_>>(), &["c"]);
I get the error Positional argument [TWO]... *must* have required(true) or last(true) set because a prior positional argument ([ONE] [ONE]) has num_args(1..). If I make argument TWO required, I just get a different error, and if I make them both required the last argument is always attached to TWO, making it impossible to accept something like ./app a b or ./app a b c d and still have ONE capture the first two values.
Describe the solution you'd like
Allow for one or more positional arguments that capture a fixed number of items, plus a "final" positional that can capture 0.. items.
Please complete the following tasks
Clap Version
4.5.4
Describe your use case
I want to build a CLI in Rust, using
clap
, which can accept some number of positional arguments with a set number of values each, and a final argument accepting whatever positional values were left over. For example,./app a b c
with a positional argument accepting 2 values, and a positional argument accepting leftovers, would assigna b
to the first arg, andc
to the second. I'm able to do this with a positional argument that accepts a single value:But if I try to have the first arg accept two values like this:
I get the error
Positional argument [TWO]... *must* have required(true) or last(true) set because a prior positional argument ([ONE] [ONE]) has num_args(1..)
. If I make argumentTWO
required, I just get a different error, and if I make them both required the last argument is always attached toTWO
, making it impossible to accept something like./app a b
or./app a b c d
and still haveONE
capture the first two values.Describe the solution you'd like
Allow for one or more positional arguments that capture a fixed number of items, plus a "final" positional that can capture
0..
items.Alternatives, if applicable
No response
Additional Context
No response