Struct bpaf::parsers::ParseOptional
source · pub struct ParseOptional<P> { /* private fields */ }
Expand description
Implementations§
source§impl<P> ParseOptional<P>
impl<P> ParseOptional<P>
sourcepub fn catch(self) -> Self
pub fn catch(self) -> Self
Handle parse failures for optional parsers
Can be useful to decide to skip parsing of some items on a command line.
When parser succeeds - catch
version would return a value as usual
if it fails - catch
would restore all the consumed values and return None.
There’s several structures that implement this attribute: ParseOptional
, ParseMany
and ParseSome
, behavior should be identical for all of them.
Those examples are very artificial and designed to show what difference catch
makes, to
actually parse arguments like in examples you should parse
or construct
enum with alternative branches
Combinatoric example
#[derive(Debug, Clone)]
pub struct Options {
height: Option<usize>,
height_str: Option<String>,
width: Option<usize>,
width_str: Option<String>,
}
pub fn options() -> OptionParser<Options> {
// contains catch
let height = long("height")
.help("Height of a rectangle")
.argument::<usize>("PX")
.optional()
.catch();
let height_str = long("height").argument::<String>("PX").optional().hide();
// contains no catch
let width = long("width")
.help("Width of a rectangle")
.argument::<usize>("PX")
.optional();
let width_str = long("width").argument::<String>("PX").optional().hide();
construct!(Options {
height,
height_str,
width,
width_str
})
.to_options()
}
fn main() {
println!("{:?}", options().run())
}
Derive example
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
#[bpaf(long, argument("PX"), optional, catch)]
/// Height of a rectangle
height: Option<usize>,
#[bpaf(long("height"), argument("PX"), optional, hide)]
height_str: Option<String>,
#[bpaf(long, argument("PX"), optional)]
/// Width of a rectangle
width: Option<usize>,
#[bpaf(long("width"), argument("PX"), optional, hide)]
width_str: Option<String>,
}
fn main() {
println!("{:?}", options().run())
}
Output
Despite parser producing a funky value - help looks like you would expect from a parser that takes two values
Usage: app [--height=PX] [--width=PX]
- --height=PX
- Height of a rectangle
- --width=PX
- Width of a rectangle
- -h, --help
- Prints help information
When executed with no parameters it produces four None
values - all parsers succeed by the
nature of them being optional
Options { height: None, height_str: None, width: None, width_str: None }
When executed with expected parameters fields with usize
get their values
Options { height: Some(100), height_str: None, width: Some(100), width_str: None }
With incorrect value for --height
parameter inner part of height
parser fails, optional
combined with catch
handles this failure and produces None
without consuming value from the
command line. Parser height_str
runs next and consumes the value as a string
Options { height: None, height_str: Some("ten"), width: None, width_str: None }
In case of wrong --width
- parser width
fails, parser for optional
sees this as a
“value is present but not correct” and propagates the error outside, execution never reaches
width_str
parser
Error: couldn't parse ten: invalid digit found in string
Examples found in repository?
More examples
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
fn feature_if() -> impl Parser<Option<String>> {
// here feature starts as any string on a command line that does not start with a dash
positional::<String>("FEATURE")
// guard restricts it such that it can't be a valid version
.guard(move |s| !is_version(s), "")
// last two steps describe what to do with strings in this position but are actually
// versions.
// optional allows parser to represent an ignored value with None
.optional()
// and catch lets optional to handle parse failures coming from guard
.catch()
}
fn version_if() -> impl Parser<Option<String>> {
positional::<String>("VERSION")
.guard(move |s| is_version(s), "")
.optional()
.catch()
}
Trait Implementations§
source§impl<T, P> Parser<Option<T>> for ParseOptional<P>where
P: Parser<T>,
impl<T, P> Parser<Option<T>> for ParseOptional<P>where
P: Parser<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.