]>
Commit | Line | Data |
---|---|---|
8bb4bdeb XL |
1 | // Std |
2 | use std::convert::From; | |
3 | use std::fmt::{Display, Formatter, Result}; | |
4 | use std::rc::Rc; | |
5 | use std::result::Result as StdResult; | |
041b39d2 XL |
6 | use std::ffi::{OsStr, OsString}; |
7 | use std::mem; | |
8bb4bdeb | 8 | |
8bb4bdeb XL |
9 | // Internal |
10 | use Arg; | |
abe05a73 XL |
11 | use args::{AnyArg, ArgSettings, Base, DispOrder, Switched}; |
12 | use map::{self, VecMap}; | |
8bb4bdeb XL |
13 | |
14 | #[derive(Default, Clone, Debug)] | |
15 | #[doc(hidden)] | |
16 | pub struct FlagBuilder<'n, 'e> | |
abe05a73 XL |
17 | where |
18 | 'n: 'e, | |
8bb4bdeb XL |
19 | { |
20 | pub b: Base<'n, 'e>, | |
21 | pub s: Switched<'e>, | |
22 | } | |
23 | ||
24 | impl<'n, 'e> FlagBuilder<'n, 'e> { | |
abe05a73 XL |
25 | pub fn new(name: &'n str) -> Self { |
26 | FlagBuilder { | |
27 | b: Base::new(name), | |
28 | ..Default::default() | |
29 | } | |
30 | } | |
8bb4bdeb XL |
31 | } |
32 | ||
33 | impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> { | |
34 | fn from(a: &'z Arg<'a, 'b>) -> Self { | |
8bb4bdeb XL |
35 | FlagBuilder { |
36 | b: Base::from(a), | |
37 | s: Switched::from(a), | |
38 | } | |
39 | } | |
40 | } | |
41 | ||
041b39d2 XL |
42 | impl<'a, 'b> From<Arg<'a, 'b>> for FlagBuilder<'a, 'b> { |
43 | fn from(mut a: Arg<'a, 'b>) -> Self { | |
44 | FlagBuilder { | |
45 | b: mem::replace(&mut a.b, Base::default()), | |
46 | s: mem::replace(&mut a.s, Switched::default()), | |
47 | } | |
48 | } | |
49 | } | |
50 | ||
8bb4bdeb XL |
51 | impl<'n, 'e> Display for FlagBuilder<'n, 'e> { |
52 | fn fmt(&self, f: &mut Formatter) -> Result { | |
53 | if let Some(l) = self.s.long { | |
3b2f2976 | 54 | write!(f, "--{}", l)?; |
8bb4bdeb | 55 | } else { |
3b2f2976 | 56 | write!(f, "-{}", self.s.short.unwrap())?; |
8bb4bdeb XL |
57 | } |
58 | ||
59 | Ok(()) | |
60 | } | |
61 | } | |
62 | ||
63 | impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> { | |
64 | fn name(&self) -> &'n str { self.b.name } | |
8bb4bdeb | 65 | fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) } |
041b39d2 XL |
66 | fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> { |
67 | self.b.requires.as_ref().map(|o| &o[..]) | |
68 | } | |
8bb4bdeb XL |
69 | fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) } |
70 | fn required_unless(&self) -> Option<&[&'e str]> { None } | |
71 | fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) } | |
72 | fn has_switch(&self) -> bool { true } | |
73 | fn takes_value(&self) -> bool { false } | |
74 | fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) } | |
75 | fn max_vals(&self) -> Option<u64> { None } | |
76 | fn val_names(&self) -> Option<&VecMap<&'e str>> { None } | |
77 | fn num_vals(&self) -> Option<u64> { None } | |
78 | fn possible_vals(&self) -> Option<&[&'e str]> { None } | |
79 | fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None } | |
041b39d2 | 80 | fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None } |
8bb4bdeb XL |
81 | fn min_vals(&self) -> Option<u64> { None } |
82 | fn short(&self) -> Option<char> { self.s.short } | |
83 | fn long(&self) -> Option<&'e str> { self.s.long } | |
84 | fn val_delim(&self) -> Option<char> { None } | |
85 | fn help(&self) -> Option<&'e str> { self.b.help } | |
041b39d2 XL |
86 | fn long_help(&self) -> Option<&'e str> { self.b.long_help } |
87 | fn val_terminator(&self) -> Option<&'e str> { None } | |
88 | fn default_val(&self) -> Option<&'e OsStr> { None } | |
abe05a73 | 89 | fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> { |
041b39d2 XL |
90 | None |
91 | } | |
abe05a73 | 92 | fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { None } |
8bb4bdeb XL |
93 | fn longest_filter(&self) -> bool { self.s.long.is_some() } |
94 | fn aliases(&self) -> Option<Vec<&'e str>> { | |
95 | if let Some(ref aliases) = self.s.aliases { | |
abe05a73 XL |
96 | let vis_aliases: Vec<_> = aliases |
97 | .iter() | |
8bb4bdeb XL |
98 | .filter_map(|&(n, v)| if v { Some(n) } else { None }) |
99 | .collect(); | |
100 | if vis_aliases.is_empty() { | |
101 | None | |
102 | } else { | |
103 | Some(vis_aliases) | |
104 | } | |
105 | } else { | |
106 | None | |
107 | } | |
108 | } | |
109 | } | |
110 | ||
111 | impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> { | |
112 | fn disp_ord(&self) -> usize { self.s.disp_ord } | |
113 | } | |
114 | ||
041b39d2 | 115 | impl<'n, 'e> PartialEq for FlagBuilder<'n, 'e> { |
abe05a73 | 116 | fn eq(&self, other: &FlagBuilder<'n, 'e>) -> bool { self.b == other.b } |
041b39d2 XL |
117 | } |
118 | ||
8bb4bdeb XL |
119 | #[cfg(test)] |
120 | mod test { | |
121 | use args::settings::ArgSettings; | |
122 | use super::FlagBuilder; | |
123 | ||
124 | #[test] | |
125 | fn flagbuilder_display() { | |
126 | let mut f = FlagBuilder::new("flg"); | |
127 | f.b.settings.set(ArgSettings::Multiple); | |
128 | f.s.long = Some("flag"); | |
129 | ||
130 | assert_eq!(&*format!("{}", f), "--flag"); | |
131 | ||
132 | let mut f2 = FlagBuilder::new("flg"); | |
133 | f2.s.short = Some('f'); | |
134 | ||
135 | assert_eq!(&*format!("{}", f2), "-f"); | |
136 | } | |
137 | ||
138 | #[test] | |
139 | fn flagbuilder_display_single_alias() { | |
140 | let mut f = FlagBuilder::new("flg"); | |
141 | f.s.long = Some("flag"); | |
142 | f.s.aliases = Some(vec![("als", true)]); | |
143 | ||
144 | assert_eq!(&*format!("{}", f), "--flag"); | |
145 | } | |
146 | ||
147 | #[test] | |
148 | fn flagbuilder_display_multiple_aliases() { | |
149 | let mut f = FlagBuilder::new("flg"); | |
150 | f.s.short = Some('f'); | |
abe05a73 XL |
151 | f.s.aliases = Some(vec![ |
152 | ("alias_not_visible", false), | |
153 | ("f2", true), | |
154 | ("f3", true), | |
155 | ("f4", true), | |
156 | ]); | |
8bb4bdeb XL |
157 | assert_eq!(&*format!("{}", f), "-f"); |
158 | } | |
159 | } |