Reputation: 333
This is a minimal version of an example from the clap crate:
use clap::{Args, Parser};
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(flatten)]
exclusive: Exclusive,
}
#[derive(Args)]
#[group(required = true, multiple = false)]
struct Exclusive {
#[arg(short)]
a: bool,
#[arg(short)]
b: bool,
}
fn main() {
let _ = Cli::parse();
}
It works just like described in the docs: I can cargo run -- -a
or cargo run -- -b
, but not cargo run -- -a -b
.
Now I would like to have options that are not bool
s but u8
s, for example (just s/bool/u8/g of the above code):
use clap::{Args, Parser};
#[derive(Parser)]
#[command(version, about, long_about = None)]
struct Cli {
#[command(flatten)]
exclusive: Exclusive,
}
#[derive(Args)]
#[group(required = true, multiple = false)]
struct Exclusive {
#[arg(short)]
a: u8,
#[arg(short)]
b: u8,
}
fn main() {
let _ = Cli::parse();
}
But that doesn't work at all:
± cargo run -- --help
Usage: bla <-a <A>|-b <B>>
Options:
-a <A>
-b <B>
-h, --help Print help
-V, --version Print version
± cargo run -- -a 1
error: The following required argument was not provided: b
Usage: bla <-a <A>|-b <B>>
± cargo run -- -b 1
error: The following required argument was not provided: a
Usage: bla <-a <A>|-b <B>>
± cargo run -- -a 1 -b 2
error: the argument '-a <A>' cannot be used with '-b <B>'
Usage: bla <-a <A>|-b <B>>
Help looks okay, but there's no way to pass a valid parameter. What's wrong with my code?
Upvotes: 3
Views: 51
Reputation: 333
The problem is solved by making the arguments optional:
#[derive(Args)]
#[group(required = true, multiple = false)]
struct Exclusive {
#[arg(short)]
a: Option<u8>,
#[arg(short)]
b: Option<u8>,
}
Upvotes: 6