我有以下设置:
use structopt::StructOpt;
#[derive(Debug, StructOpt)]
struct CliArgs {
#[structopt(short, long)]
aisle: Option<String>,
#[structopt(short, long)]
shelf: Option<String>,
#[structopt(subcommand)]
operation: Option<Ops>,
}
#[derive(Debug, StructOpt)]
enum Ops {
Add {
isbn: Option<String>,
pin: Option<String>
},
Remove {
isbn: Option<String>,
},
Status,
}
在这种情况下,我想要一个条件,其中一个aisle
和shelf
一起指定或isbn
单独指定。我发现原始的 clap 方法required_unless
和conflicts_with
,以及它们的变体required_unless_all
和conflicts_with_all
一起可以使用。
也许像这样使用它们:
...
#[structopt(short, long, required_unless = "isbn", conflicts_with = "isbn")]
aisle: Option<String>,
#[structopt(short, long, required_unless = "isbn", conflicts_with = "isbn")]
shelf: Option<String>,
...
和
...
Add {
#[structopt(required_unless_all = &["aisle", "shelf"], conflicts_with_all = &["aisle", "shelf"])]
isbn: Option<String>,
pin: Option<String>
}
...
但这会导致以下结果
~❯ RUST_BACKTRACE=full cargo run -q -- --aisle A1 --shelf X3 add 2441
error: The following required arguments were not provided:
<pin>
这是正确的,因为通过的 pin 被用作isbn
代替。
~❯ RUST_BACKTRACE=full cargo run -q -- add A1/X3 2441
error: The following required arguments were not provided:
--aisle <aisle>
--shelf <shelf>
~❯ RUST_BACKTRACE=full cargo run -q -- --aisle B1 --shelf Y3 add A1/X3 2441
<It works>
~❯ RUST_BACKTRACE=full cargo run -q -- add
error: The following required arguments were not provided:
<isbn>
<pin>
由于明显的原因,这不起作用。我认为我的问题的主要问题是如果放在子命令下,这些字段不能相互引用。我对当前的方法做错了吗?在这种情况下,是否有更好的替代 clap::arg 方法的方法?或者有没有办法在子命令之间进行通信?