Function long

Source
pub fn long(long: &'static str) -> NamedArg
Expand description

Parse a flag/switch/argument that has a long name

You can chain multiple short, long and env for multiple names. You can specify multiple names of the same type, bpaf would use items past the first one as hidden aliases.

Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
    switch: bool,
    arg: usize,
    username: String,
}

pub fn options() -> OptionParser<Options> {
    let switch = short('s') // first `short` creates a builder
        .short('S') // second switch is a hidden alias
        .long("switch") // visible long name
        .long("also-switch") // hidden alias
        .help("Switch with many names")
        .switch(); // `switch` finalizes the builder

    let arg = long("argument") // long is also a builder
        .short('a')
        .short('A')
        .long("also-arg")
        .help("Argument with names")
        .argument::<usize>("ARG");

    let username = long("user")
        .short('u')
        .env("USER1")
        .help("Custom user name")
        .argument::<String>("USER");

    construct!(Options {
        switch,
        arg,
        username
    })
    .to_options()
}

fn main() {
    println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
    #[bpaf(short, long, short('S'), long("also-switch"))]
    /// Switch with many names
    switch: bool,
    #[bpaf(short, long("argument"), short('A'), long("also-arg"))]
    /// Argument with names
    arg: usize,
    #[bpaf(short, long("user"), env("USER1"), argument("USER"))]
    /// Custom user name
    username: String,
}

fn main() {
    println!("{:?}", options().run())
}
Output

As usual switch is optional, arguments are required

$ app -a 42 -u Bobert
Options { switch: false, arg: 42, username: "Bobert" }

Help displays only visible aliases (and a current value for env arguments)

$ app --help

Usage: app [-s] -a=ARG -u=USER

Available options:
-s, --switch
Switch with many names
-a, --argument=ARG
Argument with names
-u, --user=USER
Custom user name
[env:USER1: N/A]
-h, --help
Prints help information

But you can still use hidden aliases, both short and long

$ app --also-switch --also-arg 330 --user Bobert
Options { switch: true, arg: 330, username: "Bobert" }

And unless there’s many or similar modifiers having multiple aliases doesn’t mean you can specify them multiple times:

$ app -A 42 -a 330 -u Bobert
Error: -a is not expected in this context

Also hidden aliases are really hidden and only meant to do backward compatibility stuff, they won’t show up anywhere else in completions or error messages

$ app -a 42 -A 330 -u Bobert
Error: -A is not expected in this context
Examples found in repository?
examples/dynamic.rs (line 14)
12fn number(name: &'static str) -> impl Parser<(String, Value)> {
13    let label = name.to_string();
14    long(name)
15        .argument::<usize>("NUM")
16        .map(move |n| (label.clone(), Value::Number(n)))
17}
18
19fn bool(name: &'static str) -> impl Parser<(String, Value)> {
20    let label = name.to_string();
21    long(name)
22        .switch()
23        .map(move |n| (label.clone(), Value::Bool(n)))
24}
25
26fn string(name: &'static str) -> impl Parser<(String, Value)> {
27    let label = name.to_string();
28    long(name)
29        .help("this can use a help message")
30        .argument::<String>("NUM")
31        .map(move |n| (label.clone(), Value::String(n)))
32}
More examples
Hide additional examples
examples/enum_in_args.rs (line 29)
28fn main() {
29    let opt = long("baz")
30        .short('b')
31        .help("choose between foo, bar or foobar")
32        .argument::<Baz>("CMD")
33        .to_options()
34        .run();
35
36    println!("{:#?}", opt);
37}
examples/env_variable.rs (line 12)
11pub fn main() {
12    let key = long("key")
13        .env("ACCESS_KEY")
14        .help("access key to use")
15        .argument::<String>("KEY");
16
17    let opts = construct!(Opts { key }).to_options().run();
18
19    println!("{:?}", opts);
20}
examples/ex_positional.rs (line 13)
12fn main() {
13    let value = long("value")
14        .help("Mysterious value")
15        .argument::<u32>("VAL")
16        .fallback(42);
17    let files = positional::<PathBuf>("FILE").many();
18    let opts = construct!(Options { value, files }).to_options().run();
19
20    println!("{:#?}", opts);
21}
examples/many_comma_separated_args.rs (line 7)
6fn args() -> impl Parser<Vec<u16>> {
7    long("ports")
8        .help("Comma separated list of ports")
9        .argument::<String>("PORTS")
10        .parse(|s| {
11            s.split(',')
12                .map(u16::from_str)
13                .collect::<Result<Vec<_>, _>>()
14        })
15        .many()
16        .map(|nested| nested.into_iter().flatten().collect())
17}
examples/negative.rs (line 6)
5fn main() {
6    let age = long("age").argument::<i64>("AGE");
7    let msg = "\
8To pass a value that starts with a dash requres one one of two special syntaxes:
9
10This will pass '-1' to '--age' handler and leave remaining arguments as is
11    --age=-1
12This will transform everything after '--' into non flags, '--age' will handle '-1'
13and positional handlers will be able to handle the rest.
14    --age -- -1";
15    let num = age.to_options().descr(msg).run();
16    println!("age: {}", num);
17}