From 93e915dfe300f7b7d6209ca93323c6a46f89a8c1 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Wed, 29 Jul 2015 16:25:00 -0400 Subject: [PATCH] perf: removes some unneeded allocations --- src/app.rs | 70 ++++++++++++++++++------------- src/args/arg.rs | 42 +++++++++---------- src/args/argbuilder/flag.rs | 8 ++-- src/args/argbuilder/option.rs | 50 ++++++++++------------ src/args/argbuilder/positional.rs | 15 ++++--- src/args/group.rs | 16 +++---- src/usageparser.rs | 3 -- 7 files changed, 106 insertions(+), 98 deletions(-) diff --git a/src/app.rs b/src/app.rs index 66836c53..ec40ed67 100644 --- a/src/app.rs +++ b/src/app.rs @@ -11,6 +11,9 @@ use fmt::Format; #[cfg(feature = "suggestions")] use strsim; +const INTERNAL_ERROR_MSG: &'static str = "Internal Error: Failed to write string. Please \ + consider filing a bug report!"; + /// Produces a string from a given list of possible values which is similar to /// the passed in value `v` with a certain confidence. /// Thus in a list of possible values like ["foo", "bar"], the value "fop" will yield @@ -138,7 +141,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// let prog = App::new("myprog") /// # .get_matches(); /// ``` - pub fn new(n: &'ar str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn new(n: &'ar str) -> Self { App { name: n.to_owned(), name_slice: n, @@ -188,7 +191,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .author("Me, me@mymain.com") /// # ; /// ``` - pub fn author(mut self, a: &'a str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn author(mut self, a: &'a str) -> Self { self.author = Some(a); self } @@ -207,7 +210,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .bin_name("my_binary") /// # ; /// ``` - pub fn bin_name(mut self, a: &str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn bin_name(mut self, a: &str) -> Self { self.bin_name = Some(a.to_owned()); self } @@ -223,7 +226,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .about("Does really amazing things to great people") /// # ; /// ``` - pub fn about(mut self, a: &'ab str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn about(mut self, a: &'ab str) -> Self { self.about = Some(a); self } @@ -241,7 +244,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .after_help("Does really amazing things to great people") /// # ; /// ``` - pub fn after_help(mut self, h: &'h str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn after_help(mut self, h: &'h str) -> Self { self.more_help = Some(h); self } @@ -260,7 +263,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .subcommands_negate_reqs(true) /// # ; /// ``` - pub fn subcommands_negate_reqs(mut self, n: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn subcommands_negate_reqs(mut self, n: bool) -> Self { self.subcmds_neg_reqs = n; self } @@ -277,7 +280,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .subcommand_required(true) /// # ; /// ``` - pub fn subcommand_required(mut self, n: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn subcommand_required(mut self, n: bool) -> Self { self.no_sc_error = n; self } @@ -293,7 +296,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .version("v0.1.24") /// # ; /// ``` - pub fn version(mut self, v: &'v str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn version(mut self, v: &'v str) -> Self { self.version = Some(v); self } @@ -319,7 +322,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .usage("myapp [-clDas] ") /// # ; /// ``` - pub fn usage(mut self, u: &'u str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn usage(mut self, u: &'u str) -> Self { self.usage_str = Some(u); self } @@ -358,7 +361,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// work Do some work") /// # ; /// ``` - pub fn help(mut self, h: &'u str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn help(mut self, h: &'u str) -> Self { self.help_str = Some(h); self } @@ -379,7 +382,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// // Using an uppercase `H` instead of the default lowercase `h` /// .help_short("H") /// # ; - pub fn help_short(mut self, s: &str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn help_short(mut self, s: &str) -> Self { self.help_short = s.trim_left_matches(|c| c == '-') .chars() .nth(0); @@ -402,7 +405,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// // Using a lowercase `v` instead of the default capital `V` /// .version_short("v") /// # ; - pub fn version_short(mut self, s: &str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn version_short(mut self, s: &str) -> Self { self.version_short = s.trim_left_matches(|c| c == '-') .chars() .nth(0); @@ -422,7 +425,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .arg_required_else_help(true) /// # ; /// ``` - pub fn arg_required_else_help(mut self, tf: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn arg_required_else_help(mut self, tf: bool) -> Self { self.help_on_no_args = tf; self } @@ -445,7 +448,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// // running `myprog test --version` will display /// // "myprog-test v1.1" /// ``` - pub fn global_version(mut self, gv: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn global_version(mut self, gv: bool) -> Self { self.global_ver = gv; self } @@ -468,7 +471,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .get_matches(); /// // running `myprog test --version` will display unknown argument error /// ``` - pub fn versionless_subcommands(mut self, vers: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn versionless_subcommands(mut self, vers: bool) -> Self { self.versionless_scs = Some(vers); self } @@ -488,7 +491,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .get_matches(); /// // running `myprog --help` will display a unified "docopt" or "getopts" style help message /// ``` - pub fn unified_help_message(mut self, uni_help: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn unified_help_message(mut self, uni_help: bool) -> Self { self.unified_help = uni_help; self } @@ -513,7 +516,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .arg_required_else_help(true) /// # ; /// ``` - pub fn wait_on_error(mut self, w: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn wait_on_error(mut self, w: bool) -> Self { self.wait_on_error = w; self } @@ -536,7 +539,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .subcommand_required_else_help(true) /// # ; /// ``` - pub fn subcommand_required_else_help(mut self, tf: bool) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn subcommand_required_else_help(mut self, tf: bool) -> Self { self.help_on_no_sc = tf; self } @@ -568,7 +571,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// ) /// # ; /// ``` - pub fn arg(mut self, a: Arg<'ar, 'ar, 'ar, 'ar, 'ar, 'ar>) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn arg(mut self, a: Arg<'ar, 'ar, 'ar, 'ar, 'ar, 'ar>) -> Self { self.add_arg(a); self } @@ -825,7 +828,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// # ; /// ``` pub fn args(mut self, args: Vec>) - -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + -> Self { for arg in args.into_iter() { self = self.arg(arg); } @@ -848,7 +851,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .arg_from_usage("-c --conf= 'Sets a configuration file to use'") /// # ; /// ``` - pub fn arg_from_usage(mut self, usage: &'ar str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn arg_from_usage(mut self, usage: &'ar str) -> Self { self = self.arg(Arg::from_usage(usage)); self } @@ -874,7 +877,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// ) /// # ; /// ``` - pub fn args_from_usage(mut self, usage: &'ar str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn args_from_usage(mut self, usage: &'ar str) -> Self { for l in usage.lines() { self = self.arg(Arg::from_usage(l.trim())); } @@ -913,7 +916,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .add_all(vec!["ver", "major", "minor","patch"]) /// .required(true)) /// # ; - pub fn arg_group(mut self, group: ArgGroup<'ar, 'ar>) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn arg_group(mut self, group: ArgGroup<'ar, 'ar>) -> Self { if group.required { self.required.insert(group.name); if let Some(ref reqs) = group.requires { @@ -975,7 +978,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// .add_all(vec!["ver", "major", "minor","patch"]) /// .required(true)) /// # ; - pub fn arg_groups(mut self, groups: Vec>) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + pub fn arg_groups(mut self, groups: Vec>) -> Self { for g in groups { self = self.arg_group(g); } @@ -1000,7 +1003,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// # ; /// ``` pub fn subcommand(mut self, mut subcmd: App<'a, 'v, 'ab, 'u, 'h, 'ar>) - -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + -> Self { if subcmd.name == "help" { self.needs_subcmd_help = false; } if self.versionless_scs.is_some() && self.versionless_scs.unwrap() { subcmd.versionless_scs = Some(false); @@ -1027,7 +1030,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ /// # ; /// ``` pub fn subcommands(mut self, subcmds: Vec>) - -> App<'a, 'v, 'ab, 'u, 'h, 'ar> { + -> Self { for subcmd in subcmds.into_iter() { self = self.subcommand(subcmd); } @@ -1216,6 +1219,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ // after all arguments were parsed, but before any subcommands have been parsed (so as to // give subcommands their own usage recursively) fn create_usage(&self, matches: Option>) -> String { + use ::std::fmt::Write; let mut usage = String::with_capacity(75); usage.push_str("USAGE:\n\t"); if let Some(u) = self.usage_str { @@ -1227,11 +1231,14 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ let r_string = reqs.iter().fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]); - usage.push_str(&format!("{}{}", + write!(&mut usage, "{}{}", self.usage.clone().unwrap_or(self.bin_name.clone().unwrap_or(self.name.clone())), - r_string)[..]); + r_string + ).ok().expect(INTERNAL_ERROR_MSG) } else { - usage.push_str(&self.usage.clone().unwrap_or(self.bin_name.clone().unwrap_or(self.name.clone()))[..]); + usage.push_str(&*self.usage.clone() + .unwrap_or(self.bin_name.clone() + .unwrap_or(self.name.clone()))); let mut reqs = self.required.iter().map(|n| *n).collect::>(); // If it's required we also need to ensure all previous positionals are required too @@ -1994,13 +2001,16 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{ matches.usage = Some(self.create_usage(None)); if let Some(sc_name) = subcmd_name { + use ::std::fmt::Write; let mut mid_string = String::new(); if !self.subcmds_neg_reqs { let mut hs = self.required.iter().map(|n| *n).collect::>(); matches.args.keys().map(|k| hs.push(*k)).collect::>(); let reqs = self.get_required_from(hs); - mid_string.push_str(&reqs.iter().fold(String::new(), |acc, s| acc + &format!(" {}", s)[..])[..]) + for s in reqs.iter() { + write!(&mut mid_string, " {}", s).ok().expect(INTERNAL_ERROR_MSG); + } } mid_string.push_str(" "); if let Some(ref mut sc) = self.subcommands.get_mut(&sc_name) { diff --git a/src/args/arg.rs b/src/args/arg.rs index 9bfdc86f..5fb93a93 100644 --- a/src/args/arg.rs +++ b/src/args/arg.rs @@ -112,7 +112,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// Arg::with_name("conifg") /// # .short("c") /// # ).get_matches(); - pub fn with_name(n: &'n str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn with_name(n: &'n str) -> Self { Arg { name: n, short: None, @@ -313,7 +313,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("conifg") /// .short("c") /// # ).get_matches(); - pub fn short(mut self, s: &str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn short(mut self, s: &str) -> Self { self.short = s.trim_left_matches(|c| c == '-').chars().nth(0); self } @@ -337,7 +337,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("conifg") /// .long("config") /// # ).get_matches(); - pub fn long(mut self, l: &'l str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn long(mut self, l: &'l str) -> Self { self.long = Some(l.trim_left_matches(|c| c == '-')); self } @@ -355,7 +355,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("conifg") /// .help("The config file used by the myprog") /// # ).get_matches(); - pub fn help(mut self, h: &'h str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn help(mut self, h: &'h str) -> Self { self.help = Some(h); self } @@ -379,7 +379,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("conifg") /// .required(true) /// # ).get_matches(); - pub fn required(mut self, r: bool) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn required(mut self, r: bool) -> Self { self.required = r; self } @@ -399,7 +399,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # let myprog = App::new("myprog").arg(Arg::with_name("conifg") /// .conflicts_with("debug") /// # ).get_matches(); - pub fn conflicts_with(mut self, name: &'r str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn conflicts_with(mut self, name: &'r str) -> Self { if let Some(ref mut vec) = self.blacklist { vec.push(name); } else { @@ -425,7 +425,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// .conflicts_with_all(&config_conflicts) /// # ).get_matches(); pub fn conflicts_with_all(mut self, names: I) - -> Arg<'n, 'l, 'h, 'g, 'p, 'r> + -> Self where T: AsRef + 'r, I: IntoIterator { if let Some(ref mut vec) = self.blacklist { @@ -449,7 +449,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # let myprog = App::new("myprog").arg(Arg::with_name("conifg") /// .requires("debug") /// # ).get_matches(); - pub fn requires(mut self, name: &'r str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn requires(mut self, name: &'r str) -> Self { if let Some(ref mut vec) = self.requires { vec.push(name); } else { @@ -474,7 +474,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// .requires_all(&config_reqs) /// # ).get_matches(); pub fn requires_all(mut self, names: I) - -> Arg<'n, 'l, 'h, 'g, 'p, 'r> + -> Self where T: AsRef + 'r, I: IntoIterator { if let Some(ref mut vec) = self.requires { @@ -500,7 +500,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("conifg") /// .takes_value(true) /// # ).get_matches(); - pub fn takes_value(mut self, tv: bool) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn takes_value(mut self, tv: bool) -> Self { self.takes_value = tv; self } @@ -522,7 +522,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("conifg") /// .index(1) /// # ).get_matches(); - pub fn index(mut self, idx: u8) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn index(mut self, idx: u8) -> Self { self.index = Some(idx); self } @@ -545,7 +545,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug") /// .multiple(true) /// # ).get_matches(); - pub fn multiple(mut self, multi: bool) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn multiple(mut self, multi: bool) -> Self { self.multiple = multi; self } @@ -570,7 +570,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug") /// .global(true) /// # ).get_matches(); - pub fn global(mut self, g: bool) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn global(mut self, g: bool) -> Self { self.global = g; self } @@ -590,7 +590,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug") /// .empty_values(true) /// # ).get_matches(); - pub fn empty_values(mut self, ev: bool) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn empty_values(mut self, ev: bool) -> Self { self.empty_vals = ev; self } @@ -612,7 +612,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// .possible_values(&mode_vals) /// # ).get_matches(); pub fn possible_values(mut self, names: I) - -> Arg<'n, 'l, 'h, 'g, 'p, 'r> + -> Self where T: AsRef + 'p, I: IntoIterator { if let Some(ref mut vec) = self.possible_vals { @@ -635,7 +635,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug").index(1) /// .group("mode") /// # ).get_matches(); - pub fn group(mut self, name: &'g str) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn group(mut self, name: &'g str) -> Self { self.group = Some(name); self } @@ -658,7 +658,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug").index(1) /// .number_of_values(3) /// # ).get_matches(); - pub fn number_of_values(mut self, qty: u8) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn number_of_values(mut self, qty: u8) -> Self { self.num_vals = Some(qty); self } @@ -681,7 +681,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug").index(1) /// .max_values(3) /// # ).get_matches(); - pub fn max_values(mut self, qty: u8) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn max_values(mut self, qty: u8) -> Self { if qty < 2 { panic!("Arguments with max_values(qty) qty must be > 1. Prefer \ takes_value(true) for arguments with only one value, or flags for arguments \ @@ -713,7 +713,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// # Arg::with_name("debug").index(1) /// .min_values(2) /// # ).get_matches(); - pub fn min_values(mut self, qty: u8) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + pub fn min_values(mut self, qty: u8) -> Self { if qty < 1 { panic!("Arguments with min_values(qty) qty must be > 0. Prefer flags for arguments \ with 0 values."); @@ -748,7 +748,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { /// .value_names(&val_names) /// # ).get_matches(); pub fn value_names(mut self, names: I) - -> Arg<'n, 'l, 'h, 'g, 'p, 'r> + -> Self where T: AsRef + 'n, I: IntoIterator { if let Some(ref mut vec) = self.val_names { @@ -761,7 +761,7 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> { } impl<'n, 'l, 'h, 'g, 'p, 'r, 'z> From<&'z Arg<'n, 'l, 'h, 'g, 'p, 'r>> for Arg<'n, 'l, 'h, 'g, 'p, 'r> { - fn from(a: &'z Arg<'n, 'l, 'h, 'g, 'p, 'r>) -> Arg<'n, 'l, 'h, 'g, 'p, 'r> { + fn from(a: &'z Arg<'n, 'l, 'h, 'g, 'p, 'r>) -> Self { Arg { name: a.name, short: a.short, diff --git a/src/args/argbuilder/flag.rs b/src/args/argbuilder/flag.rs index 28673f6a..64161dac 100644 --- a/src/args/argbuilder/flag.rs +++ b/src/args/argbuilder/flag.rs @@ -29,10 +29,10 @@ pub struct FlagBuilder<'n> { impl<'n> Display for FlagBuilder<'n> { fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "{}", if self.long.is_some() { - format!("--{}", self.long.unwrap()) + if let Some(l) = self.long { + write!(f, "--{}", l) } else { - format!("-{}", self.short.unwrap()) - }) + write!(f, "-{}", self.short.unwrap()) + } } } diff --git a/src/args/argbuilder/option.rs b/src/args/argbuilder/option.rs index 6d4eeff5..34759294 100644 --- a/src/args/argbuilder/option.rs +++ b/src/args/argbuilder/option.rs @@ -35,32 +35,28 @@ pub struct OptBuilder<'n> { impl<'n> Display for OptBuilder<'n> { fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "{}", - if let Some(ref vec) = self.val_names { - format!("{}{}", - if self.long.is_some() { - format!("--{}", self.long.unwrap()) - } else { - format!("-{}", self.short.unwrap()) - }, - vec.iter().fold(String::new(),|acc, i| acc + &format!(" <{}>",i)[..]) ) - } else if let Some(num) = self.num_vals { - format!("{}{}", - if self.long.is_some() { - format!("--{}", self.long.unwrap()) - } else { - format!("-{}", self.short.unwrap()) - }, - (0..num).fold(String::new(), |acc, _| acc + &format!(" <{}>", self.name)[..]) ) - } else { - format!("{} <{}>{}", - if self.long.is_some() { - format!("--{}", self.long.unwrap()) - } else { - format!("-{}", self.short.unwrap()) - }, - self.name, - if self.multiple{"..."}else{""}) - }) + // Write the name such --long or -l + if let Some(l) = self.long { + try!(write!(f, "--{}", l)); + } else { + try!(write!(f, "-{}", self.short.unwrap())); + } + + // Write the values such as + if let Some(ref vec) = self.val_names { + for n in vec.iter() { + try!(write!(f, " <{}>", n)); + } + } else { + let num = self.num_vals.unwrap_or(1); + for _ in (0..num) { + try!(write!(f, " <{}>", self.name)); + } + if self.multiple && num == 1 { + try!(write!(f, "...")); + } + } + + Ok(()) } } diff --git a/src/args/argbuilder/positional.rs b/src/args/argbuilder/positional.rs index 167b470b..d7b63594 100644 --- a/src/args/argbuilder/positional.rs +++ b/src/args/argbuilder/positional.rs @@ -32,10 +32,15 @@ pub struct PosBuilder<'n> { impl<'n> Display for PosBuilder<'n> { fn fmt(&self, f: &mut Formatter) -> Result { - write!(f, "{}{}{}{}", - if self.required { "<" } else {"["}, - self.name, - if self.required { ">" } else {"]"}, - if self.multiple {"..."}else{""}) + if self.required { + try!(write!(f, "<{}>", self.name)); + } else { + try!(write!(f, "[{}]", self.name)); + } + if self.multiple { + try!(write!(f, "...")); + } + + Ok(()) } } diff --git a/src/args/group.rs b/src/args/group.rs index 5e6c5f36..121ee2ad 100644 --- a/src/args/group.rs +++ b/src/args/group.rs @@ -62,7 +62,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # .arg_group( /// ArgGroup::with_name("conifg") /// # ).get_matches(); - pub fn with_name(n: &'n str) -> ArgGroup<'n, 'ar> { + pub fn with_name(n: &'n str) -> Self { ArgGroup { name: n, required: false, @@ -84,7 +84,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .add("config") /// # ).get_matches(); - pub fn add(mut self, n: &'ar str) -> ArgGroup<'n, 'ar> { + pub fn add(mut self, n: &'ar str) -> Self { self.args.insert(n); self } @@ -101,7 +101,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .add_all(vec!["config", "input", "output"]) /// # ).get_matches(); - pub fn add_all(mut self, ns: Vec<&'ar str>) -> ArgGroup<'n, 'ar> { + pub fn add_all(mut self, ns: Vec<&'ar str>) -> Self { for n in ns { self = self.add(n); } @@ -123,7 +123,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .required(true) /// # ).get_matches(); - pub fn required(mut self, r: bool) -> ArgGroup<'n, 'ar> { + pub fn required(mut self, r: bool) -> Self { self.required = r; self } @@ -144,7 +144,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .requires("config") /// # ).get_matches(); - pub fn requires(mut self, n: &'ar str) -> ArgGroup<'n, 'ar> { + pub fn requires(mut self, n: &'ar str) -> Self { if let Some(ref mut reqs) = self.requires { reqs.insert(n); } else { @@ -171,7 +171,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .requires_all(vec!["config", "input"]) /// # ).get_matches(); - pub fn requires_all(mut self, ns: Vec<&'ar str>) -> ArgGroup<'n, 'ar> { + pub fn requires_all(mut self, ns: Vec<&'ar str>) -> Self { for n in ns { self = self.requires(n); } @@ -194,7 +194,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .conflicts_with("config") /// # ).get_matches(); - pub fn conflicts_with(mut self, n: &'ar str) -> ArgGroup<'n, 'ar> { + pub fn conflicts_with(mut self, n: &'ar str) -> Self { if let Some(ref mut confs) = self.conflicts { confs.insert(n); } else { @@ -221,7 +221,7 @@ impl<'n, 'ar> ArgGroup<'n, 'ar> { /// # ArgGroup::with_name("conifg") /// .conflicts_with_all(vec!["config", "input"]) /// # ).get_matches(); - pub fn conflicts_with_all(mut self, ns: Vec<&'ar str>) -> ArgGroup<'n, 'ar> { + pub fn conflicts_with_all(mut self, ns: Vec<&'ar str>) -> Self { for n in ns { self = self.conflicts_with(n); } diff --git a/src/usageparser.rs b/src/usageparser.rs index 3c3ba5d3..af4cd975 100644 --- a/src/usageparser.rs +++ b/src/usageparser.rs @@ -51,11 +51,8 @@ impl<'u> Iterator for UsageParser<'u> { } if self.e > self.usage.len() { return None } - // self.e += 1; - let name = &self.usage[self.s..self.e]; - return Some(UsageToken::Name(name, if c == '<' { Some(true) } else { None })); }, Some('\'') => {