perf: doesn't run arg_post_processing on multiple values anymore

This commit is contained in:
Kevin K 2017-03-03 05:13:28 -05:00
parent 150756b989
commit 6f638a53c1
No known key found for this signature in database
GPG key ID: 17218E4B3692F01A
3 changed files with 43 additions and 23 deletions

View file

@ -148,9 +148,12 @@ macro_rules! parse_positional {
$matcher.inc_occurrence_of($p.b.name);
let _ = $_self.groups_for_arg($p.b.name)
.and_then(|vec| Some($matcher.inc_occurrences_of(&*vec)));
arg_post_processing!($_self, $p, $matcher);
if $_self.cache.map_or(true, |name| name != $p.b.name) {
arg_post_processing!($_self, $p, $matcher);
$_self.cache = Some($p.b.name);
}
$_self.set(AS::ValidArgFound);
$_self.settings.set(AS::ValidArgFound);
// Only increment the positional counter if it doesn't allow multiples
if !$p.b.settings.is_set(ArgSettings::Multiple) {
$pos_counter += 1;

View file

@ -54,6 +54,7 @@ pub struct Parser<'a, 'b>
overrides: Vec<&'b str>,
help_short: Option<char>,
version_short: Option<char>,
cache: Option<&'a str>,
help_message: Option<&'a str>,
version_message: Option<&'a str>,
}
@ -81,14 +82,6 @@ impl<'a, 'b> Parser<'a, 'b>
self.version_short = Some(c);
}
pub fn help_message(&mut self, s: &'a str) {
self.help_message = Some(s);
}
pub fn version_message(&mut self, s: &'a str) {
self.version_message = Some(s);
}
pub fn gen_completions_to<W: Write>(&mut self, for_shell: Shell, buf: &mut W) {
if !self.is_set(AS::Propogated) {
self.propogate_help_version();
@ -1289,7 +1282,7 @@ impl<'a, 'b> Parser<'a, 'b>
let arg = FlagBuilder {
b: Base {
name: "hclap_help",
help: Some(self.help_message.unwrap_or("Prints help information")),
help: Some("Prints help information"),
..Default::default()
},
s: Switched {
@ -1309,7 +1302,7 @@ impl<'a, 'b> Parser<'a, 'b>
let arg = FlagBuilder {
b: Base {
name: "vclap_version",
help: Some(self.version_message.unwrap_or("Prints version information")),
help: Some("Prints version information"),
..Default::default()
},
s: Switched {
@ -1432,8 +1425,10 @@ impl<'a, 'b> Parser<'a, 'b>
opt.to_string());
self.settings.set(AS::ValidArgFound);
let ret = try!(self.parse_opt(val, opt, val.is_some(), matcher));
self.set(AS::ValidArgFound);
arg_post_processing!(self, opt, matcher);
if self.cache.map_or(true, |name| name != opt.b.name) {
arg_post_processing!(self, opt, matcher);
self.cache = Some(opt.b.name);
}
return Ok(ret);
} else if let Some(flag) = find_flag_by_long!(@os self, &arg) {
@ -1447,9 +1442,11 @@ impl<'a, 'b> Parser<'a, 'b>
try!(self.parse_flag(flag, matcher));
// Handle conflicts, requirements, etc.
arg_post_processing!(self, flag, matcher);
if self.cache.map_or(true, |name| name != flag.b.name) {
arg_post_processing!(self, flag, matcher);
self.cache = Some(flag.b.name);
}
self.set(AS::ValidArgFound);
return Ok(None);
} else if self.is_set(AS::AllowLeadingHyphen) {
return Ok(None);
@ -1517,9 +1514,11 @@ impl<'a, 'b> Parser<'a, 'b>
// Default to "we're expecting a value later"
let ret = try!(self.parse_opt(val, opt, false, matcher));
arg_post_processing!(self, opt, matcher);
if self.cache.map_or(true, |name| name != opt.b.name) {
arg_post_processing!(self, opt, matcher);
self.cache = Some(opt.b.name);
}
self.set(AS::ValidArgFound);
return Ok(ret);
} else if let Some(flag) = find_flag_by_short!(self, c) {
debugln!("Parser::parse_short_arg:iter: Found valid short flag -{}",
@ -1529,10 +1528,12 @@ impl<'a, 'b> Parser<'a, 'b>
try!(self.check_for_help_and_version_char(c));
try!(self.parse_flag(flag, matcher));
self.set(AS::ValidArgFound);
// Handle conflicts, requirements, overrides, etc.
// Must be called here due to mutablilty
arg_post_processing!(self, flag, matcher);
if self.cache.map_or(true, |name| name != flag.b.name) {
arg_post_processing!(self, flag, matcher);
self.cache = Some(flag.b.name);
}
} else {
let arg = format!("-{}", c);
return Err(Error::unknown_argument(&*arg,
@ -2215,7 +2216,11 @@ impl<'a, 'b> Parser<'a, 'b>
if let Some(ref val) = $a.v.default_val {
if $m.get($a.b.name).is_none() {
try!($_self.add_val_to_arg($a, OsStr::new(val), $m));
arg_post_processing!($_self, $a, $m);
if $_self.cache.map_or(true, |name| name != $a.name()) {
arg_post_processing!($_self, $a, $m);
$_self.cache = Some($a.name());
}
}
}
};
@ -2235,7 +2240,10 @@ impl<'a, 'b> Parser<'a, 'b>
};
if add {
try!($_self.add_val_to_arg($a, OsStr::new(default), $m));
arg_post_processing!($_self, $a, $m);
if $_self.cache.map_or(true, |name| name != $a.name()) {
arg_post_processing!($_self, $a, $m);
$_self.cache = Some($a.name());
}
done = true;
break;
}

View file

@ -527,12 +527,18 @@ pub enum AppSettings {
/// This can be useful if there are many values, or they are explained elsewhere.
HidePossibleValuesInHelp,
/// Tries to match unknown args to partial [`subcommands`] or their aliases. For example to
/// Tries to match unknown args to partial [`subcommands`] or their [aliases]. For example to
/// match a subcommand named `test`, one could use `t`, `te`, `tes`, and `test`.
///
/// **NOTE:** The match *must not* be ambiguous at all in order to succeed. i.e. to match `te`
/// to `test` there could not also be a subcommand or alias `temp` because both start with `te`
///
/// **CAUTION:** This setting can interfere with [positional/free arguments], take care when
/// designing CLIs which allow inferred subcommands and have potential positional/free
/// arguments who's values could start with the same characters as subcommands. If this is the
/// case, it's recommended to use settings such as [`AppSeettings::ArgsNegateSubcommands`] in
/// conjuction with this setting.
///
/// # Examples
///
/// ```no_run
@ -546,6 +552,9 @@ pub enum AppSettings {
/// assert_eq!(m.subcommand_name(), Some("test"));
/// ```
/// [`subcommands`]: ./struct.SubCommand.html
/// [positional/free arguments]: ./struct.Arg.html#method.index
/// [aliases]: ./struct.App.html#method.alias
/// [`AppSeettings::ArgsNegateSubcommands`]: ./enum.AppSettings.html#variant.ArgsNegateSubcommands
InferSubcommands,
/// Specifies that the parser should not assume the first argument passed is the binary name.