clap/args/arg_builder/
flag.rs
1use std::{
3 convert::From,
4 ffi::{OsStr, OsString},
5 fmt::{Display, Formatter, Result},
6 mem,
7 rc::Rc,
8 result::Result as StdResult,
9};
10
11use crate::{
13 args::{AnyArg, Arg, ArgSettings, Base, DispOrder, Switched},
14 map::{self, VecMap},
15};
16
17#[derive(Default, Clone, Debug)]
18#[doc(hidden)]
19pub struct FlagBuilder<'n, 'e>
20where
21 'n: 'e,
22{
23 pub b: Base<'n, 'e>,
24 pub s: Switched<'e>,
25}
26
27impl<'n, 'e> FlagBuilder<'n, 'e> {
28 pub fn new(name: &'n str) -> Self {
29 FlagBuilder {
30 b: Base::new(name),
31 ..Default::default()
32 }
33 }
34}
35
36impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
37 fn from(a: &'z Arg<'a, 'b>) -> Self {
38 FlagBuilder {
39 b: Base::from(a),
40 s: Switched::from(a),
41 }
42 }
43}
44
45impl<'a, 'b> From<Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
46 fn from(mut a: Arg<'a, 'b>) -> Self {
47 FlagBuilder {
48 b: mem::take(&mut a.b),
49 s: mem::take(&mut a.s),
50 }
51 }
52}
53
54impl<'n, 'e> Display for FlagBuilder<'n, 'e> {
55 fn fmt(&self, f: &mut Formatter) -> Result {
56 if let Some(l) = self.s.long {
57 write!(f, "--{}", l)?;
58 } else {
59 write!(f, "-{}", self.s.short.unwrap())?;
60 }
61
62 Ok(())
63 }
64}
65
66impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
67 fn name(&self) -> &'n str {
68 self.b.name
69 }
70 fn overrides(&self) -> Option<&[&'e str]> {
71 self.b.overrides.as_ref().map(|o| &o[..])
72 }
73 fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
74 self.b.requires.as_ref().map(|o| &o[..])
75 }
76 fn blacklist(&self) -> Option<&[&'e str]> {
77 self.b.blacklist.as_ref().map(|o| &o[..])
78 }
79 fn required_unless(&self) -> Option<&[&'e str]> {
80 self.b.r_unless.as_ref().map(|o| &o[..])
81 }
82 fn is_set(&self, s: ArgSettings) -> bool {
83 self.b.settings.is_set(s)
84 }
85 fn has_switch(&self) -> bool {
86 true
87 }
88 fn takes_value(&self) -> bool {
89 false
90 }
91 fn set(&mut self, s: ArgSettings) {
92 self.b.settings.set(s)
93 }
94 fn max_vals(&self) -> Option<u64> {
95 None
96 }
97 fn val_names(&self) -> Option<&VecMap<&'e str>> {
98 None
99 }
100 fn num_vals(&self) -> Option<u64> {
101 None
102 }
103 fn possible_vals(&self) -> Option<&[&'e str]> {
104 None
105 }
106 #[cfg_attr(feature = "cargo-clippy", allow(clippy::type_complexity))]
107 fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
108 None
109 }
110 #[cfg_attr(feature = "cargo-clippy", allow(clippy::type_complexity))]
111 fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
112 None
113 }
114 fn min_vals(&self) -> Option<u64> {
115 None
116 }
117 fn short(&self) -> Option<char> {
118 self.s.short
119 }
120 fn long(&self) -> Option<&'e str> {
121 self.s.long
122 }
123 fn val_delim(&self) -> Option<char> {
124 None
125 }
126 fn help(&self) -> Option<&'e str> {
127 self.b.help
128 }
129 fn long_help(&self) -> Option<&'e str> {
130 self.b.long_help
131 }
132 fn val_terminator(&self) -> Option<&'e str> {
133 None
134 }
135 fn default_val(&self) -> Option<&'e OsStr> {
136 None
137 }
138 fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
139 None
140 }
141 fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
142 None
143 }
144 fn longest_filter(&self) -> bool {
145 self.s.long.is_some()
146 }
147 fn aliases(&self) -> Option<Vec<&'e str>> {
148 if let Some(ref aliases) = self.s.aliases {
149 let vis_aliases: Vec<_> = aliases
150 .iter()
151 .filter_map(|&(n, v)| if v { Some(n) } else { None })
152 .collect();
153 if vis_aliases.is_empty() {
154 None
155 } else {
156 Some(vis_aliases)
157 }
158 } else {
159 None
160 }
161 }
162}
163
164impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> {
165 fn disp_ord(&self) -> usize {
166 self.s.disp_ord
167 }
168}
169
170impl<'n, 'e> PartialEq for FlagBuilder<'n, 'e> {
171 fn eq(&self, other: &FlagBuilder<'n, 'e>) -> bool {
172 self.b == other.b
173 }
174}
175
176#[cfg(test)]
177mod test {
178 use super::FlagBuilder;
179 use crate::args::settings::ArgSettings;
180
181 #[test]
182 fn flagbuilder_display() {
183 let mut f = FlagBuilder::new("flg");
184 f.b.settings.set(ArgSettings::Multiple);
185 f.s.long = Some("flag");
186
187 assert_eq!(&*format!("{}", f), "--flag");
188
189 let mut f2 = FlagBuilder::new("flg");
190 f2.s.short = Some('f');
191
192 assert_eq!(&*format!("{}", f2), "-f");
193 }
194
195 #[test]
196 fn flagbuilder_display_single_alias() {
197 let mut f = FlagBuilder::new("flg");
198 f.s.long = Some("flag");
199 f.s.aliases = Some(vec![("als", true)]);
200
201 assert_eq!(&*format!("{}", f), "--flag");
202 }
203
204 #[test]
205 fn flagbuilder_display_multiple_aliases() {
206 let mut f = FlagBuilder::new("flg");
207 f.s.short = Some('f');
208 f.s.aliases = Some(vec![
209 ("alias_not_visible", false),
210 ("f2", true),
211 ("f3", true),
212 ("f4", true),
213 ]);
214 assert_eq!(&*format!("{}", f), "-f");
215 }
216}