How to write two conflict options with StructOpt in cli app?

I am writing a cli app with StructOpt crate. And I want to use two confilct options(-s and -i), that means user can just pass one option(-s or -i) at any one time. How can I write?

#[derive(StructOpt, Debug)]
/// mitool, pass `-h`
struct Cli {
    /// translate hex string
    #[structopt(short, long)]
    string: String,

    /// translate hex strings in a file
    #[structopt(short, long, parse(from_os_str))]
    input: PathBuf,
}
1 Like

You can add the conflicts_with attribute:

#[derive(StructOpt, Debug)]
/// mitool, pass `-h`
struct Cli {
    /// translate hex string
    #[structopt(short, long)]
    string: String,

    /// translate hex strings in a file
    #[structopt(short, long, parse(from_os_str), conflicts_with = "string")]
    input: PathBuf,
}
1 Like

Thank you for your reply. I have tried that, but when I use -s option, it will be error with, error: The argument '--string <string>' cannot be used with '--input <input>'. I just want to use one of the -s and -i.

        /// translate hex string to instr
        #[structopt(short, long, default_value="")]
        string: String,

        /// input .coe file
        #[structopt(short, long, default_value="", parse(from_os_str), conflicts_with = "string")]
        input: PathBuf,

It's because you have added a default_value - meaning that it will always in a conflict.

If I don't use default_value, when I use -s option, it will be panic with thread 'main' panicked at 'called Option::unwrap() on a None value', src/main.rs:4:10. And when I use -i option, it will be error with error: The following required arguments were not provided: --string <string>

Right, sorry about that...
You could wrap the fields with Option and check if they are Some before accessing.

#[derive(StructOpt, Debug)]
/// mitool, pass `-h`
struct Cli {
    /// translate hex string
    #[structopt(short, long)]
    string: Option<String>,

    /// translate hex strings in a file
    #[structopt(short, long, parse(from_os_str), conflicts_with = "string")]
    input: Option<PathBuf>,
}

fn main() {
    let args = Cli::from_args();
    dbg!(&args);

    if let Some(s) = args.string {
        println!("string: {}", s);
    }
}
1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.