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