pub struct ParsePositional<T> { /* private fields */ }
Expand description
Parse a positional item, created with positional
You can add extra information to positional parsers with help
,
strict
, or non_strict
on this struct.
Implementations§
source§impl<T> ParsePositional<T>
impl<T> ParsePositional<T>
sourcepub fn help<M>(self, help: M) -> Self
pub fn help<M>(self, help: M) -> Self
Add a help message to a positional
parser
bpaf
converts doc comments and string into help by following those rules:
- Everything up to the first blank line is included into a “short” help message
- Everything is included into a “long” help message
bpaf
preserves linebreaks followed by a line that starts with a space- Linebreaks are removed otherwise
You can pass anything that can be converted into Doc
, if you are not using
documentation generation functionality (doc
) this can be &str
.
Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
verbose: bool,
crate_name: String,
feature_name: Option<String>,
}
pub fn options() -> OptionParser<Options> {
let verbose = short('v')
.long("verbose")
.help("Display detailed information")
.switch();
let crate_name = positional("CRATE").help("Crate name to use");
let feature_name = positional("FEATURE")
.help("Display information about this feature")
.optional();
construct!(Options {
verbose,
// You must place positional items and commands after
// all other parsers
crate_name,
feature_name
})
.to_options()
}
fn main() {
println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
/// Display detailed information
#[bpaf(short, long)]
verbose: bool,
// You must place positional items and commands after
// all other parsers
#[bpaf(positional("CRATE"))]
/// Crate name to use
crate_name: String,
#[bpaf(positional("FEATURE"))]
/// Display information about this feature
feature_name: Option<String>,
}
fn main() {
println!("{:?}", options().run())
}
Output
Positional items show up in a separate group of arguments if they contain a help message, otherwise they will show up only in Usage part.
Usage: app [-v] CRATE [FEATURE]
- CRATE
- Crate name to use
- FEATURE
- Display information about this feature
- -v, --verbose
- Display detailed information
- -h, --help
- Prints help information
You can mix positional items with regular items
Options { verbose: true, crate_name: "bpaf", feature_name: None }
And since bpaf
API expects to have non positional items consumed before positional ones - you
can use them in a different order. In this example bpaf
corresponds to a crate_name
field and
--verbose
– to verbose
.
Options { verbose: true, crate_name: "bpaf", feature_name: None }
In previous examples optional field feature
was missing, this one contains it.
Options { verbose: false, crate_name: "bpaf", feature_name: Some("autocomplete") }
Users can use --
to tell bpaf
to treat remaining items as positionals - this might be
required to handle unusual items.
Options { verbose: false, crate_name: "bpaf", feature_name: Some("--verbose") }
Options { verbose: false, crate_name: "bpaf", feature_name: Some("--verbose") }
Without using --
bpaf
would only accept items that don’t start with -
as positional.
Error: expected CRATE, got --detailed. Pass --help for usage information
Error: expected CRATE, pass --help for usage information
You can use any
to work around this restriction.
Examples found in repository?
More examples
28 29 30 31 32 33 34 35 36 37 38 39
fn extension() -> impl Parser<(String, bool)> {
let state = any("(+|-)ext", |s: String| match s.as_str() {
"-ext" => Some(false),
"+ext" => Some(true),
_ => None,
})
.anywhere();
let name = positional::<String>("EXT")
.help("Extension to enable or disable, see documentation for the full list");
construct!(state, name).adjacent().map(|(a, b)| (b, a))
}
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
fn main() {
let file = positional::<OsString>("FILE")
.help("File name to concatenate, with no FILE or when FILE is -, read standard input")
.optional()
.parse::<_, Box<dyn Read>, std::io::Error>(|path| {
Ok(if let Some(path) = path {
if path == "-" {
Box::new(stdin())
} else {
Box::new(File::open(path)?)
}
} else {
Box::new(stdin())
})
})
.to_options()
.descr("Concatenate a file to standard output")
.run();
let reader = BufReader::new(file);
for line in reader.lines() {
println!("{}", line.unwrap());
}
}
sourcepub fn strict(self) -> ParsePositional<T>
pub fn strict(self) -> ParsePositional<T>
Changes positional parser to be a “strict” positional
Usually positional items can appear anywhere on a command line:
$ ls -d bpaf
$ ls bpaf -d
here ls
takes a positional item bpaf
and a flag -d
But in some cases it might be useful to have a stricter separation between positonal items and flags, such as passing arguments to a subprocess:
$ cargo run --example basic -- --help
here cargo
takes a --help
as a positional item and passes it to the example
bpaf
allows to require user to pass --
for positional items with strict
annotation.
bpaf
would display such positional elements differently in usage line as well.
Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
verbose: bool,
binary: String,
args: Vec<String>,
}
pub fn options() -> OptionParser<Options> {
let verbose = short('v')
.long("verbose")
.help("Produce detailed report")
.switch();
let binary = long("bin").help("Binary to execute").argument("BIN");
let args = positional("ARG")
.help("Arguments for the binary")
.strict()
.many();
construct!(Options {
verbose,
binary,
args
})
.to_options()
}
fn main() {
println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
#[bpaf(short, long)]
/// Produce detailed report
verbose: bool,
#[bpaf(long("bin"), argument("BIN"))]
/// Binary to execute
binary: String,
#[bpaf(positional("ARG"), strict, many)]
/// Arguments for the binary
args: Vec<String>,
}
fn main() {
println!("{:?}", options().run())
}
Output
Usage line for a cargo-run like app that takes an app name and possibly many strictly positional child arguments can look like this:
Usage: app [-v] --bin=BIN -- [ARG]...
- ARG
- Arguments for the binary
- -v, --verbose
- Produce detailed report
- --bin=BIN
- Binary to execute
- -h, --help
- Prints help information
Here any argument passed before double dash goes to the parser itself
Options { verbose: true, binary: "dd", args: [] }
Anything after it - collected into strict arguments
Options { verbose: false, binary: "dd", args: ["--verbose"] }
sourcepub fn non_strict(self) -> Self
pub fn non_strict(self) -> Self
Changes positional parser to be a “not strict” positional
Ensures the parser always rejects “strict” positions to the right of the separator, --
.
Essentially the inverse operation to ParsePositional::strict
, which can be used to ensure
adjacent strict and nonstrict args never conflict with eachother.
Trait Implementations§
source§impl<T: Clone> Clone for ParsePositional<T>
impl<T: Clone> Clone for ParsePositional<T>
source§fn clone(&self) -> ParsePositional<T>
fn clone(&self) -> ParsePositional<T>
1.0.0 · source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moresource§impl<T> Parser<T> for ParsePositional<T>
impl<T> Parser<T> for ParsePositional<T>
source§fn collect<C>(self) -> ParseCollect<Self, C, T>where
C: FromIterator<T>,
Self: Sized,
fn collect<C>(self) -> ParseCollect<Self, C, T>where
C: FromIterator<T>,
Self: Sized,
source§fn optional(self) -> ParseOptional<Self>
fn optional(self) -> ParseOptional<Self>
source§fn count(self) -> ParseCount<Self, T>
fn count(self) -> ParseCount<Self, T>
source§fn last(self) -> ParseLast<Self>
fn last(self) -> ParseLast<Self>
source§fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>
fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>
source§fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>
fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>
source§fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>
fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>
source§fn fallback(self, value: T) -> ParseFallback<Self, T>
fn fallback(self, value: T) -> ParseFallback<Self, T>
source§fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>
fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>
source§fn hide(self) -> ParseHide<Self>
fn hide(self) -> ParseHide<Self>
source§fn hide_usage(self) -> ParseUsage<Self>
fn hide_usage(self) -> ParseUsage<Self>
source§fn custom_usage<M>(self, usage: M) -> ParseUsage<Self>
fn custom_usage<M>(self, usage: M) -> ParseUsage<Self>
source§fn group_help<M: Into<Doc>>(self, message: M) -> ParseGroupHelp<Self>
fn group_help<M: Into<Doc>>(self, message: M) -> ParseGroupHelp<Self>
source§fn with_group_help<F>(self, f: F) -> ParseWithGroupHelp<Self, F>
fn with_group_help<F>(self, f: F) -> ParseWithGroupHelp<Self, F>
source§fn complete<M, F>(self, op: F) -> ParseComp<Self, F>
fn complete<M, F>(self, op: F) -> ParseComp<Self, F>
autocomplete
only.source§fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>
fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>
autocomplete
only.source§fn to_options(self) -> OptionParser<T>
fn to_options(self) -> OptionParser<T>
Auto Trait Implementations§
impl<T> Freeze for ParsePositional<T>
impl<T> RefUnwindSafe for ParsePositional<T>where
T: RefUnwindSafe,
impl<T> Send for ParsePositional<T>where
T: Send,
impl<T> Sync for ParsePositional<T>where
T: Sync,
impl<T> Unpin for ParsePositional<T>where
T: Unpin,
impl<T> UnwindSafe for ParsePositional<T>where
T: UnwindSafe,
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
source§unsafe fn clone_to_uninit(&self, dst: *mut T)
unsafe fn clone_to_uninit(&self, dst: *mut T)
clone_to_uninit
)