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;
6 use std::ffi::{OsStr, OsString};
7 use std::mem;
8 
9 // Internal
10 use Arg;
11 use args::{AnyArg, ArgSettings, Base, DispOrder, Switched};
12 use map::{self, VecMap};
13 
14 #[derive(Default, Clone, Debug)]
15 #[doc(hidden)]
16 pub struct FlagBuilder<'n, 'e>
17 where
18     'n: 'e,
19 {
20     pub b: Base<'n, 'e>,
21     pub s: Switched<'e>,
22 }
23 
24 impl<'n, 'e> FlagBuilder<'n, 'e> {
new(name: &'n str) -> Self25     pub fn new(name: &'n str) -> Self {
26         FlagBuilder {
27             b: Base::new(name),
28             ..Default::default()
29         }
30     }
31 }
32 
33 impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
from(a: &'z Arg<'a, 'b>) -> Self34     fn from(a: &'z Arg<'a, 'b>) -> Self {
35         FlagBuilder {
36             b: Base::from(a),
37             s: Switched::from(a),
38         }
39     }
40 }
41 
42 impl<'a, 'b> From<Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
from(mut a: Arg<'a, 'b>) -> Self43     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 
51 impl<'n, 'e> Display for FlagBuilder<'n, 'e> {
fmt(&self, f: &mut Formatter) -> Result52     fn fmt(&self, f: &mut Formatter) -> Result {
53         if let Some(l) = self.s.long {
54             write!(f, "--{}", l)?;
55         } else {
56             write!(f, "-{}", self.s.short.unwrap())?;
57         }
58 
59         Ok(())
60     }
61 }
62 
63 impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
name(&self) -> &'n str64     fn name(&self) -> &'n str { self.b.name }
overrides(&self) -> Option<&[&'e str]>65     fn overrides(&self) -> Option<&[&'e str]> { self.b.overrides.as_ref().map(|o| &o[..]) }
requires(&self) -> Option<&[(Option<&'e str>, &'n str)]>66     fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
67         self.b.requires.as_ref().map(|o| &o[..])
68     }
blacklist(&self) -> Option<&[&'e str]>69     fn blacklist(&self) -> Option<&[&'e str]> { self.b.blacklist.as_ref().map(|o| &o[..]) }
required_unless(&self) -> Option<&[&'e str]>70     fn required_unless(&self) -> Option<&[&'e str]> { self.b.r_unless.as_ref().map(|o| &o[..]) }
is_set(&self, s: ArgSettings) -> bool71     fn is_set(&self, s: ArgSettings) -> bool { self.b.settings.is_set(s) }
has_switch(&self) -> bool72     fn has_switch(&self) -> bool { true }
takes_value(&self) -> bool73     fn takes_value(&self) -> bool { false }
set(&mut self, s: ArgSettings)74     fn set(&mut self, s: ArgSettings) { self.b.settings.set(s) }
max_vals(&self) -> Option<u64>75     fn max_vals(&self) -> Option<u64> { None }
val_names(&self) -> Option<&VecMap<&'e str>>76     fn val_names(&self) -> Option<&VecMap<&'e str>> { None }
num_vals(&self) -> Option<u64>77     fn num_vals(&self) -> Option<u64> { None }
possible_vals(&self) -> Option<&[&'e str]>78     fn possible_vals(&self) -> Option<&[&'e str]> { None }
validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>>79     fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>>80     fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> { None }
min_vals(&self) -> Option<u64>81     fn min_vals(&self) -> Option<u64> { None }
short(&self) -> Option<char>82     fn short(&self) -> Option<char> { self.s.short }
long(&self) -> Option<&'e str>83     fn long(&self) -> Option<&'e str> { self.s.long }
val_delim(&self) -> Option<char>84     fn val_delim(&self) -> Option<char> { None }
help(&self) -> Option<&'e str>85     fn help(&self) -> Option<&'e str> { self.b.help }
long_help(&self) -> Option<&'e str>86     fn long_help(&self) -> Option<&'e str> { self.b.long_help }
val_terminator(&self) -> Option<&'e str>87     fn val_terminator(&self) -> Option<&'e str> { None }
default_val(&self) -> Option<&'e OsStr>88     fn default_val(&self) -> Option<&'e OsStr> { None }
default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>89     fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
90         None
91     }
env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)>92     fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> { None }
longest_filter(&self) -> bool93     fn longest_filter(&self) -> bool { self.s.long.is_some() }
aliases(&self) -> Option<Vec<&'e str>>94     fn aliases(&self) -> Option<Vec<&'e str>> {
95         if let Some(ref aliases) = self.s.aliases {
96             let vis_aliases: Vec<_> = aliases
97                 .iter()
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> {
disp_ord(&self) -> usize112     fn disp_ord(&self) -> usize { self.s.disp_ord }
113 }
114 
115 impl<'n, 'e> PartialEq for FlagBuilder<'n, 'e> {
eq(&self, other: &FlagBuilder<'n, 'e>) -> bool116     fn eq(&self, other: &FlagBuilder<'n, 'e>) -> bool { self.b == other.b }
117 }
118 
119 #[cfg(test)]
120 mod test {
121     use args::settings::ArgSettings;
122     use super::FlagBuilder;
123 
124     #[test]
flagbuilder_display()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]
flagbuilder_display_single_alias()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]
flagbuilder_display_multiple_aliases()148     fn flagbuilder_display_multiple_aliases() {
149         let mut f = FlagBuilder::new("flg");
150         f.s.short = Some('f');
151         f.s.aliases = Some(vec![
152             ("alias_not_visible", false),
153             ("f2", true),
154             ("f3", true),
155             ("f4", true),
156         ]);
157         assert_eq!(&*format!("{}", f), "-f");
158     }
159 }
160