Values after flag parsed with first argument

35 Views Asked by At

I am creating a small CLI app with clap which queries an API and returns some information based on the cli arguments.

I have 3 .arg() arguments and the first two takes values. So, I would have:

cargo run -- quick brown fox -c purple -l

It would follow this structure when I run cargo run -- --help:

USAGE:
    app_name [FLAGS] [OPTIONS] [colours]...

FLAGS:
    -h, --help         Prints help information
    -l, --low          Random flag
    -V, --version      Prints version information

OPTIONS:
    -c, --colour <colour>    Pick a colour specific colour (e.g. "blue")

ARGS:
    <words>...    Random words

I have -l not taking any values and being used to indicate the presence of something and so it does not take any arguments. If it receives any arguments, for example:

cargo run -- quick brown fox -c purple -l hello there

These are added to the <words>. This means that if I were to run:

let words = matches.values_of_lossy("words");
if let Some(w) = words {
    println!("Words are: {:?}", w);
}

the output would be:

Words are: ["quick", "brown", "fox", "hello", "there"]

How can I return an error if there are 'words' that come after the -l flag which do not take values?

I have tried handling removing the extra words but have had no success.

Added example code: lib.rs:


pub fn get_args() -> MyResult<()> {
    let matches = App::new("names")
        .version("0.1.0")
        .author("Travis")
        .about("Names in rust")
        .arg(
            Arg::with_name("words")
                .value_name("words")
                .help("Provide a few words")
                .multiple(true)
                .takes_value(true),
        )
        .arg(
            Arg::with_name("colour")
                .help("Pick a specific colour (e.g. 'blue')")
                .short("c")
                .long("colour")
                .default_value("purple")
                .takes_value(true)
                .value_name("colour")
                .empty_values(false)
                .multiple(false),
        )
        .arg(
            Arg::with_name("length")
                .help("Whether to print length or not")
                .short("l")
                .long("length")
                .takes_value(false),
        )
        .get_matches();

    let words = matches.values_of_lossy("words");

    if let Some(words) = words {
        println!("Names are: {:?}", words);
    }

    let add_length = matches.is_present("length");

    if add_length {
        println!("Length will be added");
    } else {
        println!("Length will not be added");
    }

    let colours = matches.values_of_lossy("colour");

    if let Some(c) = colours {
        println!("Colours are: {:?}", c);
    }

    Ok(())
}

main.rs:

fn main() {
    if let Err(e) = word_example::get_args() {
        eprintln!("{}", e);
        std::process::exit(1);
    }
}
0

There are 0 best solutions below