Arnav Borborah
Arnav Borborah

Reputation: 11787

How do I change the names of the values in a clap argument that takes multiple values?

As part of my CLI tool, I have a clap::Arg that takes multiple values, representing an (x, y) coordinate. I want the use the be able to pass in the value as -p/--position 1 0

.arg(
    clap::Arg::with_name("position")
        .help("The position for yada yada yada")
        .long("position")
        .short("p")
        .number_of_values(2)
        .validator(|p| match p.parse::<usize>() {
            Err(_) => Err(String::from("Error string")),
            Ok(_) => Ok(()),
        }
    )
)

While this works for the interface I want, this creates a somewhat confusing help message:

... Help text ...

OPTIONS:
    ... other options ...
    -p, --position <position> <position>    The position for yada yada yada

What bothers me here is the -p, --position <position> <position>, which seems to indicate that two positions are being passed to the argument. Is there any way I can replace the <position> <position> with strings of my choice? (My goal is to get something like -p, --position <x> <y> in the help message.)

Upvotes: 6

Views: 2967

Answers (1)

Stargateur
Stargateur

Reputation: 26757

A quick look at the documentation gives us value_names():

Specify multiple names for values of option arguments. These names are cosmetic only, used for help and usage strings only. The names are not used to access arguments. The values of the arguments are accessed in numeric order (i.e. if you specify two names one and two one will be the first matched value, two will be the second).

NOTE: This implicitly sets Arg::number_of_values if the number of value names is greater than one. I.e. be aware that the number of "names" you set for the values, will be the exact number of values required to satisfy this argument

NOTE: implicitly sets Arg::takes_value(true)

.arg(
    clap::Arg::with_name("position")
        .help("The position for yada yada yada")
        .long("position")
        .short("p")
        .value_names(&["x", "y"])
        .validator(|p| match p.parse::<usize>() {
            Err(_) => Err(String::from("Error string")),
            Ok(_) => Ok(()),
        }
    )
)

Upvotes: 6

Related Questions