pub fn long(long: &'static str) -> NamedArg
Expand description
Parse a flag
/switch
/argument
that has a long name
You can chain multiple of 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" }
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" }
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
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
Error: -A is not expected in this context
Examples found in repository?
More examples
examples/many_comma_separated_args.rs (line 7)
6 7 8 9 10 11 12 13 14 15 16 17
fn args() -> impl Parser<Vec<u16>> {
long("ports")
.help("Comma separated list of ports")
.argument::<String>("PORTS")
.parse(|s| {
s.split(',')
.map(u16::from_str)
.collect::<Result<Vec<_>, _>>()
})
.many()
.map(|nested| nested.into_iter().flatten().collect())
}
examples/negative.rs (line 6)
5 6 7 8 9 10 11 12 13 14 15 16 17
fn main() {
let age = long("age").argument::<i64>("AGE");
let msg = "\
To pass a value that starts with a dash requres one one of two special syntaxes:
This will pass '-1' to '--age' handler and leave remaining arguments as is
--age=-1
This will transform everything after '--' into non flags, '--age' will handle '-1'
and positional handlers will be able to handle the rest.
--age -- -1";
let num = age.to_options().descr(msg).run();
println!("age: {}", num);
}
examples/derive_show_asm.rs (line 49)
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
fn parse_manifest_path() -> impl Parser<PathBuf> {
long("manifest-path")
.help("Path to Cargo.toml")
.argument::<PathBuf>("PATH")
.complete_shell(ShellComp::File {
mask: Some("*.toml"),
})
.parse(|p| {
// cargo-metadata wants to see
if p.is_absolute() {
Ok(p)
} else {
std::env::current_dir()
.map(|d| d.join(p))
.and_then(|full_path| full_path.canonicalize())
}
})
.fallback_with(|| std::env::current_dir().map(|x| x.join("Cargo.toml")))
}
#[derive(Debug, Clone, Bpaf)]
/// How to render output
pub struct Format {
/// Print interleaved Rust code
pub rust: bool,
#[bpaf(external(color_detection))]
pub color: bool,
/// include full demangled name instead of just prefix
pub full_name: bool,
}
#[derive(Debug, Clone, Bpaf)]
/// Pick output type
///
/// included help
///
///
/// Extended help
pub enum Syntax {
/// Generate assembly using Intel style
Intel,
/// Generate assembly using AT&T style
Att,
}
fn color_detection() -> impl Parser<bool> {
let yes = long("color")
.help("Enable color highlighting")
.req_flag(true);
let no = long("no-color")
.help("Disable color highlighting")
.req_flag(false);
construct!([yes, no]).fallback_with::<_, Infallible>(|| {
// we can call for supports-color crate here
Ok(true)
})
}
Additional examples can be found in: