Expand description
Xorg(1)
: Xorg +xinerama +extension name
use bpaf::*;
#[derive(Debug, Clone)]
#[allow(dead_code)]
pub struct Options {
turbo: bool,
backing: bool,
xinerama: bool,
extensions: Vec<(String, bool)>,
}
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()
}
pub fn options() -> OptionParser<Options> {
let backing = toggle_options("backing", "Backing status").fallback(false);
let xinerama = toggle_options("xinerama", "Xinerama status").fallback(true);
let turbo = short('t')
.long("turbo")
.help("Engage the turbo mode")
.switch();
let extensions = extension().many();
construct!(Options {
turbo,
backing,
xinerama,
extensions,
})
.to_options()
}
fn main() {
println!("{:#?}", options().run());
}
Examples
xorg
takes parameters in a few different ways, notably as a long name starting with plus or
minus with different defaults
% app -xinerama +backing
Options { turbo: false, backing: true, xinerama: false, extensions: [] }
But also as +ext name
and -ext name
to enable or disable an extensions
% app --turbo +ext banana -ext apple
Options { turbo: true, backing: false, xinerama: true, extensions: [("banana", true), ("apple", false)] }
While bpaf
takes some effort to render the help even for custom stuff - you can always
bypass it by hiding options and substituting your own with custom header
/footer
.
% app --help
Usage: [-t] [<backing>] [<xinerama>] (<+ext> | <-ext>)...
Available positional items:
<backing> Backing status
<xinerama> Xinerama status
<+ext> enable ext <EXT>
<-ext> disable ext <EXT>
Available options:
-t, --turbo Engage the turbo mode
-h, --help Prints help information