1
2
3
4
5
6
7
8
9
10
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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
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());
}