CLAP- 使一个 arg 与一组 arg 冲突

CLAP- make an arg conflicting with a group of arg

提问人:Max G. 提问时间:11/16/2023 更新时间:11/17/2023 访问量:39

问:

您好,我正在使用 clap 构建 cli

我想实现的目标很简单: 我有 2 组参数,我有一个子命令来创建新的水果或蔬菜fruitsvegetablescreate

我可以有 2 个 sepetate 命令来创建水果和蔬菜,但我更喜欢只有一个命令并传递一个参数来创建水果 (--fruit) 或蔬菜 (--vegetable)

my_cli create --fruit // will create a fruit
my_cli create --vegetable // will create a vegetable

创建水果需要 args --weight --country 创建蔬菜 --type --destination 需要 args

如果我运行它应该弹出一个错误,因为 --fruit 将与蔬菜组中的所有参数冲突,与来自水果组的参数的 --vegetable 相同my_cli create --fruit --type "root vegetable"

有我的代码

#[derive(Parser)]
#[command(author, version, about, long_about = None)]
pub struct Cli {
    #[command(subcommand)]
    pub command: Commands,
    /// Apply command on fruit
    #[arg(
        short,
        long,
        global = true,
        conflicts_with = "vegetable",
        default_value = "true",
        default_value_if("vegetable", "true", "false"),
        display_order = 0
    )]
    pub fruit: bool,
    /// Apply command on vegetable
    #[arg(
        short,
        long,
        global = true,
        conflicts_with = "fruit",
        default_value = "false",
        default_value_if("fruit", "true", "false"),
        display_order = 0
    )]
    pub vegetable: bool,
}


#[derive(Subcommand)]
pub enum Commands {
    /// Create a new fruit or vegetable
    Create(CreateArgs),
}


#[derive(Args, Debug)]
pub struct CreateArgs {
    /// Type
    #[arg(long, display_order = 1, group = "vegetable_group")]
    pub type: Option<String>,
    /// Destination
    #[arg(long, display_order = 1, group = "vegetable_group")]
    pub destination: Option<String>,
    /// Weight
    #[arg(long, display_order = 1, group = "fruit_group")]
    pub weight: Option<String>,
    /// Country
    #[arg(long, display_order = 1, group = "fruit_group")]
    pub country: Option<String>,
}

如何使一组args与另一个args发生冲突?

我可以为所有参数做这样的事情,但是对于很多参数,这无关紧要

/// Destination
#[arg(long, display_order = 1, group = "vegetable_group", conflicts_with_all(["weight", "country"])]
pub destination: Option<String>,
rust 命令行界面 拍手

评论

0赞 Holloway 11/16/2023
您与当前 CLI 的关联程度如何?让命令 be etc、where 和 are 子命令而不是选项会更容易(对用户来说可以说更直观)。my_cli create fruit --weight 123 --country defruitvegetable
0赞 nschmeller 11/28/2023
这回答了你的问题吗?如何要求两个 Clap 选项之一?

答:

2赞 Chayim Friedman 11/17/2023 #1

Clap 子命令名称可以包含破折号,因此解决方案很简单(如果很棘手):

use clap::{Parser, Subcommand};

#[derive(Parser)]
struct Cli {
    #[command(subcommand)]
    command: CreateCommand,
}

#[derive(Subcommand)]
enum CreateCommand {
    Create {
        #[command(subcommand)]
        fruit: FruitCommands,
    },
}

#[derive(Subcommand)]
enum FruitCommands {
    #[command(name = "--fruit")]
    Fruit {
        #[arg(long)]
        weight: u32,
        #[arg(long)]
        country: String,
    },
    #[command(name = "--vegetable")]
    Vegetable {
        #[arg(long)]
        r#type: String,
        #[arg(long)]
        destination: String,
    },
}