Skip to content

Commit cf9d6ce

Browse files
committed
refactor: refactors the internals a bit
Flags, Opts, and Positionals now store their internals using compartmented Base, Valued, and Switched structs to keep the code duplication down and make it easier to maintain. Iniside the src/app/parser.rs there have been several changes to make reasoning about the code easier. Primarily moving related sections out of the large get_matches_with into their own functions.
1 parent 192a808 commit cf9d6ce

19 files changed

+825
-922
lines changed

rustfmt.toml

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
format_strings = false
22
chain_overflow_last = false
33
same_line_if_else = true
4+
fn_single_line = true

src/app/macros.rs

+52-39
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
macro_rules! remove_overriden {
22
(@remove $_self:ident, $v:ident, $a:ident.$ov:ident) => {
3-
if let Some(ref ora) = $a.$ov {
3+
if let Some(ref ora) = $a.$ov() {
44
vec_remove_all!($_self.$v, ora);
55
}
66
};
@@ -11,11 +11,11 @@ macro_rules! remove_overriden {
1111
};
1212
($_self:ident, $name:expr) => {
1313
debugln!("macro=remove_overriden!;");
14-
if let Some(ref o) = $_self.opts.iter().filter(|o| o.name == *$name).next() {
14+
if let Some(ref o) = $_self.opts.iter().filter(|o| o.b.name == *$name).next() {
1515
remove_overriden!(@arg $_self, o);
16-
} else if let Some(ref f) = $_self.flags.iter().filter(|f| f.name == *$name).next() {
16+
} else if let Some(ref f) = $_self.flags.iter().filter(|f| f.b.name == *$name).next() {
1717
remove_overriden!(@arg $_self, f);
18-
} else if let Some(p) = $_self.positionals.values().filter(|p| p.name == *$name).next() {
18+
} else if let Some(p) = $_self.positionals.values().filter(|p| p.b.name == *$name).next() {
1919
remove_overriden!(@arg $_self, p);
2020
}
2121
};
@@ -55,20 +55,7 @@ macro_rules! arg_post_processing {
5555
if $matcher.contains(c) {
5656
sdebugln!("Yes");
5757
// find who blacklisted us...
58-
$me.blacklist.push(&$arg.name);
59-
// if let Some(f) = $me.find_flag_mut(c) {
60-
// if let Some(ref mut bl) = f.blacklist {
61-
// bl.push(&$arg.name);
62-
// }
63-
// } else if let Some(o) = $me.find_option_mut(c) {
64-
// if let Some(ref mut bl) = o.blacklist {
65-
// bl.push(&$arg.name);
66-
// }
67-
// } else if let Some(p) = $me.find_positional_mut(c) {
68-
// if let Some(ref mut bl) = p.blacklist {
69-
// bl.push(&$arg.name);
70-
// }
71-
// }
58+
$me.blacklist.push(&$arg.b.name);
7259
} else {
7360
sdebugln!("No");
7461
}
@@ -130,7 +117,7 @@ macro_rules! _handle_group_reqs{
130117
macro_rules! validate_multiples {
131118
($_self:ident, $a:ident, $m:ident) => {
132119
debugln!("macro=validate_multiples!;");
133-
if $m.contains(&$a.name) && !$a.settings.is_set(ArgSettings::Multiple) {
120+
if $m.contains(&$a.b.name) && !$a.b.settings.is_set(ArgSettings::Multiple) {
134121
// Not the first time, and we don't allow multiples
135122
return Err(Error::unexpected_multiple_usage($a,
136123
&*$_self.create_current_usage($m),
@@ -159,12 +146,12 @@ macro_rules! parse_positional {
159146
return Err(e);
160147
}
161148

162-
$matcher.inc_occurrence_of($p.name);
163-
let _ = $_self.groups_for_arg($p.name)
149+
$matcher.inc_occurrence_of($p.b.name);
150+
let _ = $_self.groups_for_arg($p.b.name)
164151
.and_then(|vec| Some($matcher.inc_occurrences_of(&*vec)));
165152
arg_post_processing!($_self, $p, $matcher);
166153
// Only increment the positional counter if it doesn't allow multiples
167-
if !$p.settings.is_set(ArgSettings::Multiple) {
154+
if !$p.b.settings.is_set(ArgSettings::Multiple) {
168155
$pos_counter += 1;
169156
}
170157
};
@@ -174,24 +161,24 @@ macro_rules! find_from {
174161
($_self:ident, $arg_name:expr, $from:ident, $matcher:expr) => {{
175162
let mut ret = None;
176163
for k in $matcher.arg_names() {
177-
if let Some(f) = $_self.find_flag(k) {
178-
if let Some(ref v) = f.$from {
164+
if let Some(f) = find_by_name!($_self, &k, flags, iter) {
165+
if let Some(ref v) = f.$from() {
179166
if v.contains($arg_name) {
180167
ret = Some(f.to_string());
181168
}
182169
}
183170
}
184-
if let Some(o) = $_self.find_option(k) {
185-
if let Some(ref v) = o.$from {
171+
if let Some(o) = find_by_name!($_self, &k, opts, iter) {
172+
if let Some(ref v) = o.$from() {
186173
if v.contains(&$arg_name) {
187174
ret = Some(o.to_string());
188175
}
189176
}
190177
}
191-
if let Some(pos) = $_self.find_positional(k) {
192-
if let Some(ref v) = pos.$from {
178+
if let Some(pos) = find_by_name!($_self, &k, positionals, values) {
179+
if let Some(ref v) = pos.$from() {
193180
if v.contains($arg_name) {
194-
ret = Some(pos.name.to_owned());
181+
ret = Some(pos.b.name.to_owned());
195182
}
196183
}
197184
}
@@ -204,28 +191,54 @@ macro_rules! find_name_from {
204191
($_self:ident, $arg_name:expr, $from:ident, $matcher:expr) => {{
205192
let mut ret = None;
206193
for k in $matcher.arg_names() {
207-
if let Some(f) = $_self.find_flag(k) {
208-
if let Some(ref v) = f.$from {
194+
if let Some(f) = find_by_name!($_self, &k, flags, iter) {
195+
if let Some(ref v) = f.$from() {
209196
if v.contains($arg_name) {
210-
ret = Some(f.name);
197+
ret = Some(f.b.name);
211198
}
212199
}
213200
}
214-
if let Some(o) = $_self.find_option(k) {
215-
if let Some(ref v) = o.$from {
201+
if let Some(o) = find_by_name!($_self, &k, opts, iter) {
202+
if let Some(ref v) = o.$from() {
216203
if v.contains(&$arg_name) {
217-
ret = Some(o.name);
204+
ret = Some(o.b.name);
218205
}
219206
}
220207
}
221-
if let Some(pos) = $_self.find_positional(k) {
222-
if let Some(ref v) = pos.$from {
208+
if let Some(pos) = find_by_name!($_self, &k, positionals, values) {
209+
if let Some(ref v) = pos.$from() {
223210
if v.contains($arg_name) {
224-
ret = Some(pos.name);
211+
ret = Some(pos.b.name);
225212
}
226213
}
227214
}
228215
}
229216
ret
230217
}};
231-
}
218+
}
219+
220+
// Finds an option by name
221+
macro_rules! find_by_name {
222+
($_self:ident, $name:expr, $what:ident, $how:ident) => {
223+
$_self.$what.$how().find(|o| &o.b.name == $name)
224+
}
225+
}
226+
227+
// Finds an option including if it's aliasesed
228+
macro_rules! find_by_long {
229+
($_self:ident, $long:expr, $what:ident) => {
230+
$_self.$what
231+
.iter()
232+
.filter(|o| o.s.long.is_some())
233+
.find(|o| {
234+
&&o.s.long.unwrap() == &$long ||
235+
(o.s.aliases.is_some() &&
236+
o.s
237+
.aliases
238+
.as_ref()
239+
.unwrap()
240+
.iter()
241+
.any(|&(alias, _)| &&alias == &$long))
242+
})
243+
}
244+
}

src/app/mod.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use yaml_rust::Yaml;
2424
// Internal
2525
use app::help::Help;
2626
use app::parser::Parser;
27-
use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
27+
use args::{ArgKind, AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
2828
use errors::Error;
2929
use errors::Result as ClapResult;
3030
pub use self::settings::AppSettings;
@@ -1517,6 +1517,9 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
15171517
fn name(&self) -> &'n str {
15181518
unreachable!("App struct does not support AnyArg::name, this is a bug!")
15191519
}
1520+
fn kind(&self) -> ArgKind {
1521+
ArgKind::Subcmd
1522+
}
15201523
fn overrides(&self) -> Option<&[&'e str]> {
15211524
None
15221525
}

0 commit comments

Comments
 (0)