mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 22:32:33 +00:00
perf(matchedargs): remove unused vars and String->&str
This commit increases the performance a bit by using string slices instead of owned strings. The trade off is that code previously written to handle all the argument parsing in a speratate function and return only the ArgMatches must be re-written to add a lifetime specifier: Old code 'fn handle_args<'a>() -> ArgMatches<'a>' needs another lifetime specifier added, so now 'fn handle_args<'a, 'b>() -> ArgMatches<'a, 'b>' BREAKING CHANGE
This commit is contained in:
parent
258c97867d
commit
fd61615d1a
4 changed files with 31 additions and 30 deletions
29
src/app.rs
29
src/app.rs
|
@ -41,6 +41,7 @@ use args::{ FlagBuilder, OptBuilder, PosBuilder};
|
|||
pub struct App<'a, 'v, 'ab, 'u, 'h, 'ar> {
|
||||
// The name displayed to the user when showing version and help/usage information
|
||||
name: String,
|
||||
name_slice: &'ar str,
|
||||
// A string of author(s) if desired. Displayed when showing help/usage information
|
||||
author: Option<&'a str>,
|
||||
// The version displayed to the user
|
||||
|
@ -86,9 +87,10 @@ 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>(n: &'n str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
|
||||
pub fn new(n: &'ar str) -> App<'a, 'v, 'ab, 'u, 'h, 'ar> {
|
||||
App {
|
||||
name: n.to_owned(),
|
||||
name_slice: n,
|
||||
author: None,
|
||||
about: None,
|
||||
more_help: None,
|
||||
|
@ -725,7 +727,6 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
|
||||
// Used when spacing arguments and their help message when displaying help information
|
||||
#[inline(always)]
|
||||
fn get_spaces(&self, num: usize) -> &'static str {
|
||||
match num {
|
||||
0 => "",
|
||||
|
@ -785,7 +786,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
|
||||
// Starts the parsing process. Called on top level parent app **ONLY** then recursively calls
|
||||
// the real parsing function for subcommands
|
||||
pub fn get_matches(mut self) -> ArgMatches<'ar> {
|
||||
pub fn get_matches(mut self) -> ArgMatches<'ar, 'ar> {
|
||||
self.verify_positionals();
|
||||
for (_,sc) in self.subcommands.iter_mut() {
|
||||
sc.verify_positionals();
|
||||
|
@ -844,7 +845,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
}
|
||||
|
||||
fn get_matches_from(&mut self, matches: &mut ArgMatches<'ar>, it: &mut IntoIter<String>) {
|
||||
fn get_matches_from(&mut self, matches: &mut ArgMatches<'ar, 'ar>, it: &mut IntoIter<String>) {
|
||||
self.create_help_and_version();
|
||||
|
||||
let mut pos_only = false;
|
||||
|
@ -951,7 +952,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
// Was an update made, or is this the first occurrence?
|
||||
if !done {
|
||||
matches.args.insert(p.name, MatchedArg{
|
||||
name: p.name.to_owned(),
|
||||
// name: p.name.to_owned(),
|
||||
occurrences: 1,
|
||||
values: Some(vec![arg.clone()]),
|
||||
});
|
||||
|
@ -1008,7 +1009,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
sc.bin_name = Some(format!("{}{}{}", self.bin_name.clone().unwrap_or("".to_owned()),if self.bin_name.is_some() {" "} else {""}, sc.name.clone()));
|
||||
sc.get_matches_from(&mut new_matches, it);
|
||||
matches.subcommand = Some(Box::new(SubCommand{
|
||||
name: sc.name.clone(),
|
||||
name: sc.name_slice,
|
||||
matches: new_matches}));
|
||||
}
|
||||
}
|
||||
|
@ -1060,7 +1061,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
}
|
||||
|
||||
fn parse_long_arg(&mut self, matches: &mut ArgMatches<'ar> ,full_arg: &String) -> Option<&'ar str> {
|
||||
fn parse_long_arg(&mut self, matches: &mut ArgMatches<'ar, 'ar> ,full_arg: &String) -> Option<&'ar str> {
|
||||
let mut arg = full_arg.trim_left_matches(|c| c == '-');
|
||||
|
||||
if arg == "help" && self.needs_long_help {
|
||||
|
@ -1116,7 +1117,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
} else {
|
||||
matches.args.insert(v.name, MatchedArg{
|
||||
name: v.name.to_owned(),
|
||||
// name: v.name.to_owned(),
|
||||
occurrences: if arg_val.is_some() { 1 } else { 0 },
|
||||
values: if arg_val.is_some() { Some(vec![arg_val.clone().unwrap()])} else { Some(vec![]) }
|
||||
});
|
||||
|
@ -1167,7 +1168,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
if !done {
|
||||
matches.args.insert(v.name, MatchedArg{
|
||||
name: v.name.to_owned(),
|
||||
// name: v.name.to_owned(),
|
||||
occurrences: 1,
|
||||
values: None
|
||||
});
|
||||
|
@ -1203,7 +1204,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
unreachable!();
|
||||
}
|
||||
|
||||
fn parse_short_arg(&mut self, matches: &mut ArgMatches<'ar> ,full_arg: &String) -> Option<&'ar str> {
|
||||
fn parse_short_arg(&mut self, matches: &mut ArgMatches<'ar, 'ar> ,full_arg: &String) -> Option<&'ar str> {
|
||||
let arg = &full_arg[..].trim_left_matches(|c| c == '-');
|
||||
if arg.len() > 1 {
|
||||
// Multiple flags using short i.e. -bgHlS
|
||||
|
@ -1239,7 +1240,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
} else {
|
||||
matches.args.insert(v.name, MatchedArg{
|
||||
name: v.name.to_owned(),
|
||||
// name: v.name.to_owned(),
|
||||
// occurrences will be incremented on getting a value
|
||||
occurrences: 0,
|
||||
values: Some(vec![])
|
||||
|
@ -1273,7 +1274,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
unreachable!();
|
||||
}
|
||||
|
||||
fn parse_single_short_flag(&mut self, matches: &mut ArgMatches<'ar>, arg: char) -> bool {
|
||||
fn parse_single_short_flag(&mut self, matches: &mut ArgMatches<'ar, 'ar>, arg: char) -> bool {
|
||||
for v in self.flags.values().filter(|&v| v.short.is_some()).filter(|&v| v.short.unwrap() == arg) {
|
||||
// Ensure this flag isn't on the mutually excludes list
|
||||
if self.blacklist.contains(v.name) {
|
||||
|
@ -1293,7 +1294,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
}
|
||||
if !done {
|
||||
matches.args.insert(v.name, MatchedArg{
|
||||
name: v.name.to_owned(),
|
||||
// name: v.name.to_owned(),
|
||||
occurrences: 1,
|
||||
values: None
|
||||
});
|
||||
|
@ -1325,7 +1326,7 @@ impl<'a, 'v, 'ab, 'u, 'h, 'ar> App<'a, 'v, 'ab, 'u, 'h, 'ar>{
|
|||
false
|
||||
}
|
||||
|
||||
fn validate_blacklist(&self, matches: &ArgMatches<'ar>) {
|
||||
fn validate_blacklist(&self, matches: &ArgMatches<'ar, 'ar>) {
|
||||
for name in self.blacklist.iter() {
|
||||
if matches.args.contains_key(name) {
|
||||
self.report_error(format!("The argument {} cannot be used with one or more of the other specified arguments",
|
||||
|
|
|
@ -52,16 +52,16 @@ use args::MatchedArg;
|
|||
/// println!("Not printing testing lists...");
|
||||
/// }
|
||||
/// }
|
||||
pub struct ArgMatches<'a> {
|
||||
pub struct ArgMatches<'n, 'a> {
|
||||
#[doc(hidden)]
|
||||
pub args: HashMap<&'a str, MatchedArg>,
|
||||
#[doc(hidden)]
|
||||
pub subcommand: Option<Box<SubCommand<'a>>>,
|
||||
pub subcommand: Option<Box<SubCommand<'n, 'a>>>,
|
||||
#[doc(hidden)]
|
||||
pub usage: Option<String>
|
||||
}
|
||||
|
||||
impl<'a> ArgMatches<'a> {
|
||||
impl<'n, 'a> ArgMatches<'n, 'a> {
|
||||
/// Creates a new instance of `ArgMatches`. This ins't called directly, but
|
||||
/// through the `.get_matches()` method of `App`
|
||||
///
|
||||
|
@ -72,7 +72,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// let matches = App::new("myprog").get_matches();
|
||||
/// ```
|
||||
#[doc(hidden)]
|
||||
pub fn new() -> ArgMatches<'a> {
|
||||
pub fn new() -> ArgMatches<'n, 'a> {
|
||||
ArgMatches {
|
||||
args: HashMap::new(),
|
||||
subcommand: None,
|
||||
|
@ -96,7 +96,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// println!("Value for output: {}", o);
|
||||
/// }
|
||||
/// ```
|
||||
pub fn value_of<'n>(&self, name: &'n str) -> Option<&str> {
|
||||
pub fn value_of<'na>(&self, name: &'na str) -> Option<&str> {
|
||||
if let Some(ref arg) = self.args.get(name) {
|
||||
if let Some(ref vals) = arg.values {
|
||||
if let Some(ref val) = vals.iter().nth(0) {
|
||||
|
@ -125,7 +125,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// }
|
||||
/// }
|
||||
/// ```
|
||||
pub fn values_of<'n>(&'a self, name: &'n str) -> Option<Vec<&'a str>> {
|
||||
pub fn values_of<'na>(&'a self, name: &'na str) -> Option<Vec<&'a str>> {
|
||||
if let Some(ref arg) = self.args.get(name) {
|
||||
if let Some(ref vals) = arg.values {
|
||||
return Some(vals.iter().map(|s| &s[..]).collect::<Vec<_>>());
|
||||
|
@ -146,7 +146,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// println!("The output argument was used!");
|
||||
/// }
|
||||
/// ```
|
||||
pub fn is_present<'n>(&self, name: &'n str) -> bool {
|
||||
pub fn is_present<'na>(&self, name: &'na str) -> bool {
|
||||
if let Some(ref sc) = self.subcommand {
|
||||
if sc.name == name { return true; }
|
||||
}
|
||||
|
@ -170,7 +170,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// println!("Debug mode kind of on");
|
||||
/// }
|
||||
/// ```
|
||||
pub fn occurrences_of<'n>(&self, name: &'n str) -> u8 {
|
||||
pub fn occurrences_of<'na>(&self, name: &'na str) -> u8 {
|
||||
if let Some(ref arg) = self.args.get(name) {
|
||||
return arg.occurrences;
|
||||
}
|
||||
|
@ -190,7 +190,7 @@ impl<'a> ArgMatches<'a> {
|
|||
/// // Use matches as normal
|
||||
/// }
|
||||
/// ```
|
||||
pub fn subcommand_matches<'n>(&self, name: &'n str) -> Option<&ArgMatches> {
|
||||
pub fn subcommand_matches<'na>(&self, name: &'na str) -> Option<&ArgMatches> {
|
||||
if let Some( ref sc) = self.subcommand {
|
||||
if sc.name != name { return None; }
|
||||
return Some(&sc.matches);
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#[doc(hidden)]
|
||||
pub struct MatchedArg {
|
||||
#[doc(hidden)]
|
||||
pub name: String,
|
||||
// #[doc(hidden)]
|
||||
// pub name: String,
|
||||
#[doc(hidden)]
|
||||
pub occurrences: u8,
|
||||
#[doc(hidden)]
|
||||
|
|
|
@ -20,12 +20,12 @@ use ArgMatches;
|
|||
/// .help("The configuration file to use")
|
||||
/// .index(1))
|
||||
/// # ).get_matches();
|
||||
pub struct SubCommand<'a> {
|
||||
pub name: String,
|
||||
pub matches: ArgMatches<'a>
|
||||
pub struct SubCommand<'n, 'a> {
|
||||
pub name: &'n str,
|
||||
pub matches: ArgMatches<'n, 'a>
|
||||
}
|
||||
|
||||
impl<'a> SubCommand<'a> {
|
||||
impl<'n, 'a> SubCommand<'n, 'a> {
|
||||
/// Creates a new instance of a subcommand requiring a name. Will be displayed
|
||||
/// to the user when they print version or help and usage information.
|
||||
///
|
||||
|
@ -37,7 +37,7 @@ impl<'a> SubCommand<'a> {
|
|||
/// SubCommand::new("config")
|
||||
/// # ).get_matches();
|
||||
/// ```
|
||||
pub fn new<'n, 'au, 'v, 'ab, 'u, 'h, 'ar>(name: &'n str) -> App<'au, 'v, 'ab, 'u, 'h, 'ar> {
|
||||
pub fn new<'au, 'v, 'ab, 'u, 'h, 'ar>(name: &'ar str) -> App<'au, 'v, 'ab, 'u, 'h, 'ar> {
|
||||
App::new(name)
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue