1

我有以下设置:

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,
}

在这种情况下,我想要一个条件,其中一个aisleshelf一起指定或isbn单独指定。我发现原始的 clap 方法required_unlessconflicts_with,以及它们的变体required_unless_allconflicts_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 方法的方法?或者有没有办法在子命令之间进行通信?

4

0 回答 0