]> git.proxmox.com Git - rustc.git/blob - src/vendor/clap/src/args/arg_builder/option.rs
New upstream version 1.23.0+dfsg1
[rustc.git] / src / vendor / clap / src / args / arg_builder / option.rs
1 // Std
2 use std::fmt::{Display, Formatter, Result};
3 use std::rc::Rc;
4 use std::result::Result as StdResult;
5 use std::ffi::{OsStr, OsString};
6 use std::mem;
7
8 // Internal
9 use args::{AnyArg, Arg, ArgSettings, Base, DispOrder, Switched, Valued};
10 use map::{self, VecMap};
11 use INTERNAL_ERROR_MSG;
12
13 #[allow(missing_debug_implementations)]
14 #[doc(hidden)]
15 #[derive(Default, Clone)]
16 pub struct OptBuilder<'n, 'e>
17 where
18 'n: 'e,
19 {
20 pub b: Base<'n, 'e>,
21 pub s: Switched<'e>,
22 pub v: Valued<'n, 'e>,
23 }
24
25 impl<'n, 'e> OptBuilder<'n, 'e> {
26 pub fn new(name: &'n str) -> Self {
27 OptBuilder {
28 b: Base::new(name),
29 ..Default::default()
30 }
31 }
32 }
33
34 impl<'n, 'e, 'z> From<&'z Arg<'n, 'e>> for OptBuilder<'n, 'e> {
35 fn from(a: &'z Arg<'n, 'e>) -> Self {
36 OptBuilder {
37 b: Base::from(a),
38 s: Switched::from(a),
39 v: Valued::from(a),
40 }
41 }
42 }
43
44 impl<'n, 'e> From<Arg<'n, 'e>> for OptBuilder<'n, 'e> {
45 fn from(mut a: Arg<'n, 'e>) -> Self {
46 a.v.fill_in();
47 OptBuilder {
48 b: mem::replace(&mut a.b, Base::default()),
49 s: mem::replace(&mut a.s, Switched::default()),
50 v: mem::replace(&mut a.v, Valued::default()),
51 }
52 }
53 }
54
55 impl<'n, 'e> Display for OptBuilder<'n, 'e> {
56 fn fmt(&self, f: &mut Formatter) -> Result {
57 debugln!("OptBuilder::fmt:{}", self.b.name);
58 let sep = if self.b.is_set(ArgSettings::RequireEquals) {
59 "="
60 } else {
61 " "
62 };
63 // Write the name such --long or -l
64 if let Some(l) = self.s.long {
65 write!(f, "--{}{}", l, sep)?;
66 } else {
67 write!(f, "-{}{}", self.s.short.unwrap(), sep)?;
68 }
69 let delim = if self.is_set(ArgSettings::RequireDelimiter) {
70 self.v.val_delim.expect(INTERNAL_ERROR_MSG)
71 } else {
72 ' '
73 };
74
75 // Write the values such as <name1> <name2>
76 if let Some(ref vec) = self.v.val_names {
77 let mut it = vec.iter().peekable();
78 while let Some((_, val)) = it.next() {
79 write!(f, "<{}>", val)?;
80 if it.peek().is_some() {
81 write!(f, "{}", delim)?;
82 }
83 }
84 let num = vec.len();
85 if self.is_set(ArgSettings::Multiple) && num == 1 {
86 write!(f, "...")?;
87 }
88 } else if let Some(num) = self.v.num_vals {
89 let mut it = (0..num).peekable();
90 while let Some(_) = it.next() {
91 write!(f, "<{}>", self.b.name)?;
92 if it.peek().is_some() {
93 write!(f, "{}", delim)?;
94 }
95 }
96 if self.is_set(ArgSettings::Multiple) && num == 1 {
97 write!(f, "...")?;
98 }
99 } else {
100 write!(
101 f,
102 "<{}>{}",
103 self.b.name,
104 if self.is_set(ArgSettings::Multiple) {
105 "..."
106 } else {
107 ""
108 }
109 )?;
110 }
111
112 Ok(())
113 }
114 }
115
116 impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
117 fn name(&self) -> &'n str { self.b.name }
118 fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
119 fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
120 self.b.requires.as_ref().map(|o| &o[..])
121 }
122 fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
123 fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
124 fn val_names(&self) -> Option<&VecMap<&'e str>> { self.v.val_names.as_ref() }
125 fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
126 fn has_switch(&self) -> bool { true }
127 fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
128 fn max_vals(&self) -> Option<u64> { self.v.max_vals }
129 fn val_terminator(&self) -> Option<&'e str> { self.v.terminator }
130 fn num_vals(&self) -> Option<u64> { self.v.num_vals }
131 fn possible_vals(&self) -> Option<&[&'e str]> { self.v.possible_vals.as_ref().map(|o| &o[..]) }
132 fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
133 self.v.validator.as_ref()
134 }
135 fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
136 self.v.validator_os.as_ref()
137 }
138 fn min_vals(&self) -> Option<u64> { self.v.min_vals }
139 fn short(&self) -> Option<char> { self.s.short }
140 fn long(&self) -> Option<&'e str> { self.s.long }
141 fn val_delim(&self) -> Option<char> { self.v.val_delim }
142 fn takes_value(&self) -> bool { true }
143 fn help(&self) -> Option<&'e str> { self.b.help }
144 fn long_help(&self) -> Option<&'e str> { self.b.long_help }
145 fn default_val(&self) -> Option<&'e OsStr> { self.v.default_val }
146 fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
147 self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
148 }
149 fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
150 self.v
151 .env
152 .as_ref()
153 .map(|&(key, ref value)| (key, value.as_ref()))
154 }
155 fn longest_filter(&self) -> bool { true }
156 fn aliases(&self) -> Option<Vec<&'e str>> {
157 if let Some(ref aliases) = self.s.aliases {
158 let vis_aliases: Vec<_> = aliases
159 .iter()
160 .filter_map(|&(n, v)| if v { Some(n) } else { None })
161 .collect();
162 if vis_aliases.is_empty() {
163 None
164 } else {
165 Some(vis_aliases)
166 }
167 } else {
168 None
169 }
170 }
171 }
172
173 impl<'n, 'e> DispOrder for OptBuilder<'n, 'e> {
174 fn disp_ord(&self) -> usize { self.s.disp_ord }
175 }
176
177 impl<'n, 'e> PartialEq for OptBuilder<'n, 'e> {
178 fn eq(&self, other: &OptBuilder<'n, 'e>) -> bool { self.b == other.b }
179 }
180
181 #[cfg(test)]
182 mod test {
183 use args::settings::ArgSettings;
184 use super::OptBuilder;
185 use map::VecMap;
186
187 #[test]
188 fn optbuilder_display1() {
189 let mut o = OptBuilder::new("opt");
190 o.s.long = Some("option");
191 o.b.settings.set(ArgSettings::Multiple);
192
193 assert_eq!(&*format!("{}", o), "--option <opt>...");
194 }
195
196 #[test]
197 fn optbuilder_display2() {
198 let mut v_names = VecMap::new();
199 v_names.insert(0, "file");
200 v_names.insert(1, "name");
201
202 let mut o2 = OptBuilder::new("opt");
203 o2.s.short = Some('o');
204 o2.v.val_names = Some(v_names);
205
206 assert_eq!(&*format!("{}", o2), "-o <file> <name>");
207 }
208
209 #[test]
210 fn optbuilder_display3() {
211 let mut v_names = VecMap::new();
212 v_names.insert(0, "file");
213 v_names.insert(1, "name");
214
215 let mut o2 = OptBuilder::new("opt");
216 o2.s.short = Some('o');
217 o2.v.val_names = Some(v_names);
218 o2.b.settings.set(ArgSettings::Multiple);
219
220 assert_eq!(&*format!("{}", o2), "-o <file> <name>");
221 }
222
223 #[test]
224 fn optbuilder_display_single_alias() {
225 let mut o = OptBuilder::new("opt");
226 o.s.long = Some("option");
227 o.s.aliases = Some(vec![("als", true)]);
228
229 assert_eq!(&*format!("{}", o), "--option <opt>");
230 }
231
232 #[test]
233 fn optbuilder_display_multiple_aliases() {
234 let mut o = OptBuilder::new("opt");
235 o.s.long = Some("option");
236 o.s.aliases = Some(vec![
237 ("als_not_visible", false),
238 ("als2", true),
239 ("als3", true),
240 ("als4", true),
241 ]);
242 assert_eq!(&*format!("{}", o), "--option <opt>");
243 }
244 }