• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Std
2 use std::convert::From;
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, Switched};
11 use map::{self, VecMap};
12 use Arg;
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 {
65         self.b.name
66     }
overrides(&self) -> Option<&[&'e str]>67     fn overrides(&self) -> Option<&[&'e str]> {
68         self.b.overrides.as_ref().map(|o| &o[..])
69     }
requires(&self) -> Option<&[(Option<&'e str>, &'n str)]>70     fn requires(&self) -> Option<&[(Option<&'e str>, &'n str)]> {
71         self.b.requires.as_ref().map(|o| &o[..])
72     }
blacklist(&self) -> Option<&[&'e str]>73     fn blacklist(&self) -> Option<&[&'e str]> {
74         self.b.blacklist.as_ref().map(|o| &o[..])
75     }
required_unless(&self) -> Option<&[&'e str]>76     fn required_unless(&self) -> Option<&[&'e str]> {
77         self.b.r_unless.as_ref().map(|o| &o[..])
78     }
is_set(&self, s: ArgSettings) -> bool79     fn is_set(&self, s: ArgSettings) -> bool {
80         self.b.settings.is_set(s)
81     }
has_switch(&self) -> bool82     fn has_switch(&self) -> bool {
83         true
84     }
takes_value(&self) -> bool85     fn takes_value(&self) -> bool {
86         false
87     }
set(&mut self, s: ArgSettings)88     fn set(&mut self, s: ArgSettings) {
89         self.b.settings.set(s)
90     }
max_vals(&self) -> Option<u64>91     fn max_vals(&self) -> Option<u64> {
92         None
93     }
val_names(&self) -> Option<&VecMap<&'e str>>94     fn val_names(&self) -> Option<&VecMap<&'e str>> {
95         None
96     }
num_vals(&self) -> Option<u64>97     fn num_vals(&self) -> Option<u64> {
98         None
99     }
possible_vals(&self) -> Option<&[&'e str]>100     fn possible_vals(&self) -> Option<&[&'e str]> {
101         None
102     }
validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>>103     fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
104         None
105     }
validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>>106     fn validator_os(&self) -> Option<&Rc<Fn(&OsStr) -> StdResult<(), OsString>>> {
107         None
108     }
min_vals(&self) -> Option<u64>109     fn min_vals(&self) -> Option<u64> {
110         None
111     }
short(&self) -> Option<char>112     fn short(&self) -> Option<char> {
113         self.s.short
114     }
long(&self) -> Option<&'e str>115     fn long(&self) -> Option<&'e str> {
116         self.s.long
117     }
val_delim(&self) -> Option<char>118     fn val_delim(&self) -> Option<char> {
119         None
120     }
help(&self) -> Option<&'e str>121     fn help(&self) -> Option<&'e str> {
122         self.b.help
123     }
long_help(&self) -> Option<&'e str>124     fn long_help(&self) -> Option<&'e str> {
125         self.b.long_help
126     }
val_terminator(&self) -> Option<&'e str>127     fn val_terminator(&self) -> Option<&'e str> {
128         None
129     }
default_val(&self) -> Option<&'e OsStr>130     fn default_val(&self) -> Option<&'e OsStr> {
131         None
132     }
default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>>133     fn default_vals_ifs(&self) -> Option<map::Values<(&'n str, Option<&'e OsStr>, &'e OsStr)>> {
134         None
135     }
env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)>136     fn env<'s>(&'s self) -> Option<(&'n OsStr, Option<&'s OsString>)> {
137         None
138     }
longest_filter(&self) -> bool139     fn longest_filter(&self) -> bool {
140         self.s.long.is_some()
141     }
aliases(&self) -> Option<Vec<&'e str>>142     fn aliases(&self) -> Option<Vec<&'e str>> {
143         if let Some(ref aliases) = self.s.aliases {
144             let vis_aliases: Vec<_> = aliases
145                 .iter()
146                 .filter_map(|&(n, v)| if v { Some(n) } else { None })
147                 .collect();
148             if vis_aliases.is_empty() {
149                 None
150             } else {
151                 Some(vis_aliases)
152             }
153         } else {
154             None
155         }
156     }
157 }
158 
159 impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> {
disp_ord(&self) -> usize160     fn disp_ord(&self) -> usize {
161         self.s.disp_ord
162     }
163 }
164 
165 impl<'n, 'e> PartialEq for FlagBuilder<'n, 'e> {
eq(&self, other: &FlagBuilder<'n, 'e>) -> bool166     fn eq(&self, other: &FlagBuilder<'n, 'e>) -> bool {
167         self.b == other.b
168     }
169 }
170 
171 #[cfg(test)]
172 mod test {
173     use super::FlagBuilder;
174     use args::settings::ArgSettings;
175 
176     #[test]
flagbuilder_display()177     fn flagbuilder_display() {
178         let mut f = FlagBuilder::new("flg");
179         f.b.settings.set(ArgSettings::Multiple);
180         f.s.long = Some("flag");
181 
182         assert_eq!(&*format!("{}", f), "--flag");
183 
184         let mut f2 = FlagBuilder::new("flg");
185         f2.s.short = Some('f');
186 
187         assert_eq!(&*format!("{}", f2), "-f");
188     }
189 
190     #[test]
flagbuilder_display_single_alias()191     fn flagbuilder_display_single_alias() {
192         let mut f = FlagBuilder::new("flg");
193         f.s.long = Some("flag");
194         f.s.aliases = Some(vec![("als", true)]);
195 
196         assert_eq!(&*format!("{}", f), "--flag");
197     }
198 
199     #[test]
flagbuilder_display_multiple_aliases()200     fn flagbuilder_display_multiple_aliases() {
201         let mut f = FlagBuilder::new("flg");
202         f.s.short = Some('f');
203         f.s.aliases = Some(vec![
204             ("alias_not_visible", false),
205             ("f2", true),
206             ("f3", true),
207             ("f4", true),
208         ]);
209         assert_eq!(&*format!("{}", f), "-f");
210     }
211 }
212