rustcommand-line-interfaceclap

How do I require one of the two Clap options?


I am trying to write a CLI in Rust with the help of Clap. My command has 2 arguments, I want to make that just one or another can be specified, ex: command --command_a or command --command_b

#[derive(Debug, clap::Args)]
#[clap(name = "command")]
pub struct MyCommand {
    /// Argument1.
    #[clap(long, short)]
    command_a: String,
    /// Argument2.
    #[clap(long, short)]
    command_b: String,
    /// other optional events.
    #[clap(name = "others", long)]
    other_commands: Option<String>,
}

I can make both optional by adding command_a: Option<String>, and then in the code check that at least one has been provided, but can I do that using Clap?


Solution

  • You need to introduce an ArgGroup. To do that with the derive macros, create a struct Group and store it in MyCommand, and define it to be a group that is required but disallow multiple values:

    #[derive(Debug, clap::Args)]
    #[clap(name = "command")]
    pub struct MyCommand {
        #[clap(flatten)]
        group: Group,
        #[clap(name = "others", long)]
        other_commands: Option<String>,
    }
    
    #[derive(Debug, clap::Args)]
    #[group(required = true, multiple = false)]
    pub struct Group {
        /// Argument1.
        #[clap(short, long)]
        command_a: Option<String>,
        /// Argument2.
        #[clap(short, long)]
        command_b: Option<String>,
    }