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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use crate::{Filter, Getter};
use clap::{ArgMatches, Values};
fn _dig<'a, 'b, 'c, IT: Iterator<Item = &'c str>>(
m: &'a ArgMatches<'b>,
down: &'c str,
mut i: IT,
) -> Option<(&'a ArgMatches<'b>, &'c str)> {
match i.next() {
None => Some((m, down)),
Some(s) => _dig(m.subcommand_matches(down)?, s, i),
}
}
fn dig<'a, 'b, 'c>(m: &'a ArgMatches<'b>, s: &'c str) -> Option<(&'a ArgMatches<'b>, &'c str)> {
let mut it = s.split(".");
_dig(m, it.next()?, it)
}
impl<'a, 'b> Getter<'a,&'a str> for &'a ArgMatches<'b> {
type Iter = Values<'a>;
fn bool_flag<S: AsRef<str>>(&self, s: S, f: Filter) -> bool {
if f != Filter::Arg {
return false;
}
let (r, dot_last) = match dig(self, s.as_ref()) {
Some(v) => v,
None => return false,
};
r.is_present(dot_last)
}
fn value<S: AsRef<str>>(&self, s: S, f: Filter) -> Option<&'a str> {
if f != Filter::Arg {
return None;
}
let (r, dot_last) = dig(self, s.as_ref())?;
r.value_of(dot_last)
}
fn values<S: AsRef<str>>(&self, s: S, f: Filter) -> Option<Values<'a>> {
if f != Filter::Arg {
return None;
}
let (r, dot_last) = dig(self, s.as_ref())?;
r.values_of(dot_last)
}
fn sub<S: AsRef<str>>(&self, s: S, f: Filter) -> bool {
if f != Filter::Arg {
return false;
}
let (r, dot_last) = match dig(self, s.as_ref()) {
Some(v) => v,
None => return false,
};
match r.subcommand_matches(dot_last) {
Some(_) => true,
None => false,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use clap::clap_app;
#[test]
pub fn test_sub_get() {
let m = clap_app!(
test_app=>
(@arg a : -a +takes_value "astuff")
(@subcommand subby =>
(@arg b: -b +takes_value "bstuff")
)
)
.get_matches_from("test_app -a hi subby -b world".split(" "));
let mm = &m;
assert_eq!(mm.sub("a", Filter::Arg), false, "A");
assert_eq!(mm.grab().arg("a").done(), Some("hi"), "HI");
assert_eq!(mm.sub("subby", Filter::Arg), true, "--Sub Subby--");
assert_eq!(mm.grab().arg("subby.b").done(), Some("world"), "C");
assert_eq!(mm.bool_flag("a", Filter::Arg), true);
}
}