1 // Std
2 use std::borrow::Cow;
3 use std::ffi::{OsStr, OsString};
4 use std::fmt::{Display, Formatter, Result};
5 use std::mem;
6 use std::rc::Rc;
7 use std::result::Result as StdResult;
8 
9 // Internal
10 use args::{AnyArg, ArgSettings, Base, DispOrder, Valued};
11 use map::{self, VecMap};
12 use Arg;
13 use INTERNAL_ERROR_MSG;
14 
15 #[allow(missing_debug_implementations)]
16 #[doc(hidden)]
17 #[derive(Clone, Default)]
18 pub struct PosBuilder<'n, 'e>
19 where
20     'n: 'e,
21 {
22     pub b: Base<'n, 'e>,
23     pub v: Valued<'n, 'e>,
24     pub index: u64,
25 }
26 
27 impl<'n, 'e> PosBuilder<'n, 'e> {
new(name: &'n str, idx: u64) -> Self28     pub fn new(name: &'n str, idx: u64) -> Self {
29         PosBuilder {
30             b: Base::new(name),
31             index: idx,
32             ..Default::default()
33         }
34     }
35 
from_arg_ref(a: &Arg<'n, 'e>, idx: u64) -> Self36     pub fn from_arg_ref(a: &Arg<'n, 'e>, idx: u64) -> Self {
37         let mut pb = PosBuilder {
38             b: Base::from(a),
39             v: Valued::from(a),
40             index: idx,
41         };
42         if a.v.max_vals.is_some()
43             || a.v.min_vals.is_some()
44             || (a.v.num_vals.is_some() && a.v.num_vals.unwrap() > 1)
45         {
46             pb.b.settings.set(ArgSettings::Multiple);
47         }
48         pb
49     }
50 
from_arg(mut a: Arg<'n, 'e>, idx: u64) -> Self51     pub fn from_arg(mut a: Arg<'n, 'e>, idx: u64) -> Self {
52         if a.v.max_vals.is_some()
53             || a.v.min_vals.is_some()
54             || (a.v.num_vals.is_some() && a.v.num_vals.unwrap() > 1)
55         {
56             a.b.settings.set(ArgSettings::Multiple);
57         }
58         PosBuilder {
59             b: mem::replace(&mut a.b, Base::default()),
60             v: mem::replace(&mut a.v, Valued::default()),
61             index: idx,
62         }
63     }
64 
multiple_str(&self) -> &str65     pub fn multiple_str(&self) -> &str {
66         let mult_vals = self
67             .v
68             .val_names
69             .as_ref()
70             .map_or(true, |names| names.len() < 2);
71         if self.is_set(ArgSettings::Multiple) && mult_vals {
72             "..."
73         } else {
74             ""
75         }
76     }
77 
name_no_brackets(&self) -> Cow<str>78     pub fn name_no_brackets(&self) -> Cow<str> {
79         debugln!("PosBuilder::name_no_brackets;");
80         let mut delim = String::new();
81         delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
82             self.v.val_delim.expect(INTERNAL_ERROR_MSG)
83         } else {
84             ' '
85         });
86         if let Some(ref names) = self.v.val_names {
87             debugln!("PosBuilder:name_no_brackets: val_names={:#?}", names);
88             if names.len() > 1 {
89                 Cow::Owned(
90                     names
91                         .values()
92                         .map(|n| format!("<{}>", n))
93                         .collect::<Vec<_>>()
94                         .join(&*delim),
95                 )
96             } else {
97                 Cow::Borrowed(names.values().next().expect(INTERNAL_ERROR_MSG))
98             }
99         } else {
100             debugln!("PosBuilder:name_no_brackets: just name");
101             Cow::Borrowed(self.b.name)
102         }
103     }
104 }
105 
106 impl<'n, 'e> Display for PosBuilder<'n, 'e> {
fmt(&self, f: &mut Formatter) -> Result107     fn fmt(&self, f: &mut Formatter) -> Result {
108         let mut delim = String::new();
109         delim.push(if self.is_set(ArgSettings::RequireDelimiter) {
110             self.v.val_delim.expect(INTERNAL_ERROR_MSG)
111         } else {
112             ' '
113         });
114         if let Some(ref names) = self.v.val_names {
115             write!(
116                 f,
117                 "{}",
118                 names
119                     .values()
120                     .map(|n| format!("<{}>", n))
121                     .collect::<Vec<_>>()
122                     .join(&*delim)
123             )?;
124         } else {
125             write!(f, "<{}>", self.b.name)?;
126         }
127         if self.b.settings.is_set(ArgSettings::Multiple)
128             && (self.v.val_names.is_none() || self.v.val_names.as_ref().unwrap().len() == 1)
129         {
130             write!(f, "...")?;
131         }
132 
133         Ok(())
134     }
135 }
136 
137 impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
name(&self) -> &'n str138     fn name(&self) -> &'n str {
139         self.b.name
140     }
overrides(&self) -> Option<&[&'e str]>141     fn overrides(&self) -> Option<&[&'e str]> {
142         self.b.overrides.as_ref().map(|o| &o[..])
143     }
requires(&self) -> Option<&[(Option<&'e str>, &'n str)]>144     fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
145         self.b.requires.as_ref().map(|o| &o[..])
146     }
blacklist(&self) -> Option<&[&'e str]>147     fn blacklist(&self) -> Option<&[&'e str]> {
148         self.b.blacklist.as_ref().map(|o| &o[..])
149     }
required_unless(&self) -> Option<&[&'e str]>150     fn required_unless(&self) -> Option<&[&'e str]> {
151         self.b.r_unless.as_ref().map(|o| &o[..])
152     }
val_names(&self) -> Option<&VecMap<&'e str>>153     fn val_names(&self) -> Option<&VecMap<&'e str>> {
154         self.v.val_names.as_ref()
155     }
is_set(&self, s: ArgSettings) -> bool156     fn is_set(&self, s: ArgSettings) -> bool {
157         self.b.settings.is_set(s)
158     }
set(&mut self, s: ArgSettings)159     fn set(&mut self, s: ArgSettings) {
160         self.b.settings.set(s)
161     }
has_switch(&self) -> bool162     fn has_switch(&self) -> bool {
163         false
164     }
max_vals(&self) -> Option<u64>165     fn max_vals(&self) -> Option<u64> {
166         self.v.max_vals
167     }
val_terminator(&self) -> Option<&'e str>168     fn val_terminator(&self) -> Option<&'e str> {
169         self.v.terminator
170     }
num_vals(&self) -> Option<u64>171     fn num_vals(&self) -> Option<u64> {
172         self.v.num_vals
173     }
possible_vals(&self) -> Option<&[&'e str]>174     fn possible_vals(&self) -> Option<&[&'e str]> {
175         self.v.possible_vals.as_ref().map(|o| &o[..])
176     }
validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>>177     fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
178         self.v.validator.as_ref()
179     }
validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>>180     fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
181         self.v.validator_os.as_ref()
182     }
min_vals(&self) -> Option<u64>183     fn min_vals(&self) -> Option<u64> {
184         self.v.min_vals
185     }
short(&self) -> Option<char>186     fn short(&self) -> Option<char> {
187         None
188     }
long(&self) -> Option<&'e str>189     fn long(&self) -> Option<&'e str> {
190         None
191     }
val_delim(&self) -> Option<char>192     fn val_delim(&self) -> Option<char> {
193         self.v.val_delim
194     }
takes_value(&self) -> bool195     fn takes_value(&self) -> bool {
196         true
197     }
help(&self) -> Option<&'e str>198     fn help(&self) -> Option<&'e str> {
199         self.b.help
200     }
long_help(&self) -> Option<&'e str>201     fn long_help(&self) -> Option<&'e str> {
202         self.b.long_help
203     }
default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>204     fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
205         self.v.default_vals_ifs.as_ref().map(|vm| vm.values())
206     }
default_val(&self) -> Option<&'e OsStr>207     fn default_val(&self) -> Option<&'e OsStr> {
208         self.v.default_val
209     }
env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)>210     fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
211         self.v
212             .env
213             .as_ref()
214             .map(|&(key, ref value)| (key, value.as_ref()))
215     }
longest_filter(&self) -> bool216     fn longest_filter(&self) -> bool {
217         true
218     }
aliases(&self) -> Option<Vec<&'e str>>219     fn aliases(&self) -> Option<Vec<&'e str>> {
220         None
221     }
222 }
223 
224 impl<'n, 'e> DispOrder for PosBuilder<'n, 'e> {
disp_ord(&self) -> usize225     fn disp_ord(&self) -> usize {
226         self.index as usize
227     }
228 }
229 
230 impl<'n, 'e> PartialEq for PosBuilder<'n, 'e> {
eq(&self, other: &PosBuilder<'n, 'e>) -> bool231     fn eq(&self, other: &PosBuilder<'n, 'e>) -> bool {
232         self.b == other.b
233     }
234 }
235 
236 #[cfg(test)]
237 mod test {
238     use super::PosBuilder;
239     use args::settings::ArgSettings;
240     use map::VecMap;
241 
242     #[test]
display_mult()243     fn display_mult() {
244         let mut p = PosBuilder::new("pos", 1);
245         p.b.settings.set(ArgSettings::Multiple);
246 
247         assert_eq!(&*format!("{}", p), "<pos>...");
248     }
249 
250     #[test]
display_required()251     fn display_required() {
252         let mut p2 = PosBuilder::new("pos", 1);
253         p2.b.settings.set(ArgSettings::Required);
254 
255         assert_eq!(&*format!("{}", p2), "<pos>");
256     }
257 
258     #[test]
display_val_names()259     fn display_val_names() {
260         let mut p2 = PosBuilder::new("pos", 1);
261         let mut vm = VecMap::new();
262         vm.insert(0, "file1");
263         vm.insert(1, "file2");
264         p2.v.val_names = Some(vm);
265 
266         assert_eq!(&*format!("{}", p2), "<file1> <file2>");
267     }
268 
269     #[test]
display_val_names_req()270     fn display_val_names_req() {
271         let mut p2 = PosBuilder::new("pos", 1);
272         p2.b.settings.set(ArgSettings::Required);
273         let mut vm = VecMap::new();
274         vm.insert(0, "file1");
275         vm.insert(1, "file2");
276         p2.v.val_names = Some(vm);
277 
278         assert_eq!(&*format!("{}", p2), "<file1> <file2>");
279     }
280 }
281