pub struct ParseAny<T> { /* private fields */ }
Expand description
Parse the next available item on a command line with no restrictions, created with any
.
Implementations§
source§impl<T> ParseAny<T>
impl<T> ParseAny<T>
sourcepub fn help<M: Into<String>>(self, help: M) -> Self
pub fn help<M: Into<String>>(self, help: M) -> Self
Add a help message to any
parser.
Combinatoric usage
#[derive(Debug, Clone)]
pub struct Options {
turbo: bool,
rest: Vec<OsString>,
}
pub fn options() -> OptionParser<Options> {
let turbo = short('t')
.long("turbo")
.help("Engage the turbo mode")
.switch();
let rest = any::<OsString>("REST")
.help("app will pass anything unused to a child process")
.guard(|x| x != "--help", "keep help")
.many();
construct!(Options { turbo, rest }).to_options()
}
Derive usage
#[derive(Debug, Clone, Bpaf)]
#[bpaf(options)]
pub struct Options {
#[bpaf(short, long)]
/// Engage the turbo mode
turbo: bool,
#[bpaf(any("REST"), guard(not_help, "keep help"), many)]
/// app will pass anything unused to a child process
rest: Vec<OsString>,
}
fn not_help(s: &OsString) -> bool {
s != "--help"
}
Examples
Capture --turbo
flag for internal use and return everything else as is so it can be passed
to some other program. Anything except for --turbo
here and in following examples is
consumed by any
% app --turbo git commit -m "hello world"
Options { turbo: true, rest: ["git", "commit", "-m", "hello world"] }
Or just capture and return everything
% app git commit -m "hello world"
Options { turbo: false, rest: ["git", "commit", "-m", "hello world"] }
Doesn’t have to be in order either
% app git commit -m="hello world" --turbo
Options { turbo: true, rest: ["git", "commit", "-m=hello world"] }
You can keep --help
working, but you need to add extra guard
for that
% app --turbo --help
Usage: [-t] <REST>...
Available positional items:
<REST> app will pass anything unused to a child process
Available options:
-t, --turbo Engage the turbo mode
-h, --help Prints help information
Examples found in repository?
examples/find.rs (line 45)
43 44 45 46 47 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
fn exec() -> impl Parser<Option<Vec<OsString>>> {
let tag = any::<String>("-exec")
.help("-exec /path/to/command flags and options ;")
.guard(|s| s == "-exec", "not find");
let item = any::<OsString>("ITEM")
.guard(|s| s != ";", "not word")
.many()
.catch()
.hide();
let endtag = any::<String>("END").guard(|s| s == ";", "not eot").hide();
construct!(tag, item, endtag)
.anywhere()
.map(|triple| triple.1)
.optional()
.catch()
}
/// parses symbolic permissions `-perm -mode`, `-perm /mode` and `-perm mode`
fn perm() -> impl Parser<Option<Perm>> {
fn parse_mode(input: &str) -> Result<Perms, String> {
let mut perms = Perms::default();
for c in input.chars() {
match c {
'r' => perms.read = true,
'w' => perms.write = true,
'x' => perms.exec = true,
_ => return Err(format!("{} is not a valid permission string", input)),
}
}
Ok(perms)
}
let tag = any::<String>("-mode").help("-mode (perm | -perm | /perm)");
let mode = any::<String>("mode")
.parse::<_, _, String>(|s| {
if let Some(m) = s.strip_prefix('-') {
Ok(Perm::All(parse_mode(m)?))
} else if let Some(m) = s.strip_prefix('/') {
Ok(Perm::Any(parse_mode(m)?))
} else {
Ok(Perm::Exact(parse_mode(&s)?))
}
})
.hide();
construct!(tag, mode)
.anywhere()
.map(|pair| pair.1)
.optional()
.catch()
}
More examples
examples/dd.rs (line 23)
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
fn tag<T>(name: &'static str, meta: &'static str, help: &'static str) -> impl Parser<T>
where
T: FromStr,
<T as std::str::FromStr>::Err: std::fmt::Display,
{
// it is possible to parse OsString here and strip the prefix with os_str_bytes or a similar
// crate
any::<String>(meta)
.help(help)
.parse::<_, _, String>(move |s| match s.strip_prefix(name) {
None => Err("Wrong tag".to_string()),
Some(body) => T::from_str(body).map_err(|e| e.to_string()),
})
.anywhere()
}
examples/xorg.rs (line 13)
11 12 13 14 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 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
fn toggle_options(name: &'static str, help: &'static str) -> impl Parser<bool> {
any::<String>(name)
.help(help)
.parse(move |s| {
let (state, cur_name) = if let Some(rest) = s.strip_prefix('+') {
(true, rest)
} else if let Some(rest) = s.strip_prefix('-') {
(false, rest)
} else {
return Err(format!("{} is not a toggle option", s));
};
if cur_name != name {
Err(format!("{} is not a known toggle option name", cur_name))
} else {
Ok(state)
}
})
.anywhere()
}
fn extension() -> impl Parser<(String, bool)> {
let on = any::<String>("+ext")
.help("enable ext <EXT>")
.parse::<_, _, String>(|s| {
if s == "+ext" {
Ok(true)
} else {
Err(String::new())
}
});
let off = any::<String>("-ext")
.help("disable ext <EXT>")
.parse::<_, _, String>(|s| {
if s == "-ext" {
Ok(false)
} else {
Err(String::new())
}
});
let state = construct!([on, off]);
let name = positional::<String>("EXT").hide();
construct!(state, name).map(|(a, b)| (b, a)).anywhere()
}
Trait Implementations§
source§impl<T> Parser<T> for ParseAny<T>where
T: FromStr + 'static,
<T as FromStr>::Err: Display,
impl<T> Parser<T> for ParseAny<T>where
T: FromStr + 'static,
<T as FromStr>::Err: Display,
source§fn some(self, message: &'static str) -> ParseSome<Self>where
Self: Sized + Parser<T>,
fn some(self, message: &'static str) -> ParseSome<Self>where
Self: Sized + Parser<T>,
Consume one or more items from a command line Read more
source§fn optional(self) -> ParseOptional<Self>where
Self: Sized + Parser<T>,
fn optional(self) -> ParseOptional<Self>where
Self: Sized + Parser<T>,
Turn a required argument into optional one Read more
source§fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>where
Self: Sized + Parser<T>,
F: Fn(T) -> Result<R, E>,
E: ToString,
fn parse<F, R, E>(self, f: F) -> ParseWith<T, Self, F, E, R>where
Self: Sized + Parser<T>,
F: Fn(T) -> Result<R, E>,
E: ToString,
Apply a failing transformation to a contained value Read more
source§fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>where
Self: Sized + Parser<T>,
F: Fn(T) -> R + 'static,
fn map<F, R>(self, map: F) -> ParseMap<T, Self, F, R>where
Self: Sized + Parser<T>,
F: Fn(T) -> R + 'static,
Apply a pure transformation to a contained value Read more
source§fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>where
Self: Sized + Parser<T>,
F: Fn(&T) -> bool,
fn guard<F>(self, check: F, message: &'static str) -> ParseGuard<Self, F>where
Self: Sized + Parser<T>,
F: Fn(&T) -> bool,
Validate or fail with a message Read more
source§fn fallback(self, value: T) -> ParseFallback<Self, T>where
Self: Sized + Parser<T>,
fn fallback(self, value: T) -> ParseFallback<Self, T>where
Self: Sized + Parser<T>,
Use this value as default if value isn’t present on a command line Read more
source§fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>where
Self: Sized + Parser<T>,
F: Fn() -> Result<T, E>,
E: ToString,
fn fallback_with<F, E>(self, fallback: F) -> ParseFallbackWith<T, Self, F, E>where
Self: Sized + Parser<T>,
F: Fn() -> Result<T, E>,
E: ToString,
Use value produced by this function as default if value isn’t present Read more
source§fn hide(self) -> ParseHide<Self>where
Self: Sized + Parser<T>,
fn hide(self) -> ParseHide<Self>where
Self: Sized + Parser<T>,
Ignore this parser during any sort of help generation Read more
source§fn hide_usage(self) -> ParseHideUsage<Self>where
Self: Sized + Parser<T>,
fn hide_usage(self) -> ParseHideUsage<Self>where
Self: Sized + Parser<T>,
Ignore this parser when generating usage line Read more
source§fn group_help(self, message: &'static str) -> ParseGroupHelp<Self>where
Self: Sized + Parser<T>,
fn group_help(self, message: &'static str) -> ParseGroupHelp<Self>where
Self: Sized + Parser<T>,
Attach help message to a complex parser Read more
source§fn complete<M, F>(self, op: F) -> ParseComp<Self, F>where
M: Into<String>,
F: Fn(&T) -> Vec<(M, Option<M>)>,
Self: Sized + Parser<T>,
fn complete<M, F>(self, op: F) -> ParseComp<Self, F>where
M: Into<String>,
F: Fn(&T) -> Vec<(M, Option<M>)>,
Self: Sized + Parser<T>,
Dynamic shell completion Read more
source§fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>where
Self: Sized + Parser<T>,
fn complete_shell(self, op: ShellComp) -> ParseCompShell<Self>where
Self: Sized + Parser<T>,
Static shell completion Read more
source§fn complete_style(self, style: CompleteDecor) -> ParseCompStyle<Self>where
Self: Sized + Parser<T>,
fn complete_style(self, style: CompleteDecor) -> ParseCompStyle<Self>where
Self: Sized + Parser<T>,
Add extra annotations to completion information Read more
source§fn adjacent(self) -> ParseAdjacent<Self>where
Self: Sized + Parser<T>,
fn adjacent(self) -> ParseAdjacent<Self>where
Self: Sized + Parser<T>,
Automagically restrict the inner parser scope to accept adjacent values only Read more
source§fn anywhere(self) -> ParseAnywhere<Self>where
Self: Sized + Parser<T>,
fn anywhere(self) -> ParseAnywhere<Self>where
Self: Sized + Parser<T>,
Parse anywhere Read more