Function bpaf::batteries::cargo_helper

source ·
pub fn cargo_helper<P, T>(cmd: &'static str, parser: P) -> impl Parser<T>where
    P: Parser<T>,
Expand description

Strip a command name if present at the front when used as a cargo command

When implementing a cargo subcommand parser needs to be able to skip the first argument which is always the same as the executable name without cargo- prefix. For example if executable name is cargo-cmd so first argument would be cmd. cargo_helper helps to support both invocations: with name present when used via cargo and without it when used locally.

You can read the code of this function as this approximate sequence of statements:

  1. Want to parse a word
  2. Word must match a given string literal
  3. It’s okay if it’s missing
  4. It’s also okay when it’s not matching expectations, don’t consume it in this case
  5. And don’t show anything to the user in --help or completion
  6. Parse this word and then everything else as a tuple, return that second item.
Combinatoric usage
#[derive(Debug, Clone)]
pub struct Options {
    argument: usize,
    switch: bool,
}

pub fn options() -> OptionParser<Options> {
    let argument = long("argument")
        .help("An argument")
        .argument::<usize>("ARG");
    let switch = short('s').help("A switch").switch();
    let options = construct!(Options { argument, switch });

    cargo_helper("pretty", options).to_options()
}
Derive usage
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options("pretty"))]
pub struct Options {
    /// An argument
    argument: usize,
    /// A switch
    #[bpaf(short)]
    switch: bool,
}
Examples

Let’s say the goal is to parse an argument and a switch:

% app --argument 15
Options { argument: 15, switch: false }

But when used as a cargo subcommand, cargo will also pass the command name, this example uses wrong subcommand name to bypass the helper and show how it would look without it

% app wrong --argument 15
No such command: `wrong`, did you mean `-s`?

When used with the right command - helper simply consumes it

% app pretty --argument 42 -s
Options { argument: 42, switch: true }

And it doesn’t show up in --help so not to confuse users

% app --help
Usage: --argument ARG [-s]

Available options:
        --argument <ARG>  An argument
    -s                    A switch
    -h, --help            Prints help information