From 3cd9174f4838d02adeb711a0e4004716b3405f3c Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Feb 2022 12:42:30 -0600 Subject: [PATCH 1/5] refactor(usage): Decouple from the parser This is a step towards removing `pub(crate)` and for moving usage/help out of the core clap generally. --- src/build/app/mod.rs | 2 +- src/output/help.rs | 2 +- src/output/usage.rs | 124 +++++++++++++++++------------------------ src/parse/parser.rs | 27 ++++----- src/parse/validator.rs | 26 ++++----- 5 files changed, 81 insertions(+), 100 deletions(-) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index dc90cd23..2e6bbc5f 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -822,7 +822,7 @@ impl<'help> App<'help> { let mut parser = Parser::new(self); parser._build(); - Usage::new(&parser).create_usage_with_title(&[]) + Usage::new(&parser.app, &parser.required).create_usage_with_title(&[]) } } diff --git a/src/output/help.rs b/src/output/help.rs index f09140b4..eefb5411 100644 --- a/src/output/help.rs +++ b/src/output/help.rs @@ -962,7 +962,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { self.warning("USAGE:")?; } "usage" => { - self.none(Usage::new(self.parser).create_usage_no_title(&[]))?; + self.none(Usage::new(&self.parser.app, &self.parser.required).create_usage_no_title(&[]))?; } "all-args" => { self.write_all_args()?; diff --git a/src/output/usage.rs b/src/output/usage.rs index fb641a94..8eaf171b 100644 --- a/src/output/usage.rs +++ b/src/output/usage.rs @@ -3,19 +3,20 @@ use indexmap::IndexSet; // Internal use crate::{ build::AppSettings as AS, - build::{Arg, ArgSettings}, - parse::{ArgMatcher, Parser}, - util::Id, + build::{App, Arg, ArgSettings}, + parse::ArgMatcher, + util::{ChildGraph, Id}, INTERNAL_ERROR_MSG, }; -pub(crate) struct Usage<'help, 'app, 'parser> { - p: &'parser Parser<'help, 'app>, +pub(crate) struct Usage<'help, 'app> { + app: &'app App<'help>, + required: &'app ChildGraph, } -impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { - pub(crate) fn new(p: &'parser Parser<'help, 'app>) -> Self { - Usage { p } +impl<'help, 'app> Usage<'help, 'app> { + pub(crate) fn new(app: &'app App<'help>, required: &'app ChildGraph) -> Self { + Usage { app, required } } // Creates a usage string for display. This happens just after all arguments were parsed, but before @@ -31,7 +32,7 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { // Creates a usage string (*without title*) if one was not provided by the user manually. pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String { debug!("Usage::create_usage_no_title"); - if let Some(u) = self.p.app.usage_str { + if let Some(u) = self.app.usage_str { String::from(&*u) } else if used.is_empty() { self.create_help_usage(true) @@ -45,12 +46,11 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs); let mut usage = String::with_capacity(75); let name = self - .p .app .usage .as_ref() - .or_else(|| self.p.app.bin_name.as_ref()) - .unwrap_or(&self.p.app.name); + .or_else(|| self.app.bin_name.as_ref()) + .unwrap_or(&self.app.name); usage.push_str(&*name); let req_string = if incl_reqs { self.get_required_usage_from(&[], None, false) @@ -64,30 +64,27 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { usage.push_str(" [OPTIONS]"); } - let allow_missing_positional = self.p.app.is_set(AS::AllowMissingPositional); + let allow_missing_positional = self.app.is_set(AS::AllowMissingPositional); if !allow_missing_positional { usage.push_str(&req_string); } let has_last = self - .p .app .get_positionals() .any(|p| p.is_set(ArgSettings::Last)); // places a '--' in the usage string if there are args and options // supporting multiple values if self - .p .app .get_non_positionals() .any(|o| o.is_set(ArgSettings::MultipleValues)) && self - .p .app .get_positionals() .any(|p| !p.is_set(ArgSettings::Required)) - && !(self.p.app.has_visible_subcommands() - || self.p.is_set(AS::AllowExternalSubcommands)) + && !(self.app.has_visible_subcommands() + || self.app.is_set(AS::AllowExternalSubcommands)) && !has_last { usage.push_str(" [--]"); @@ -96,7 +93,7 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { (!p.is_set(ArgSettings::Required) || p.is_set(ArgSettings::Last)) && !p.is_set(ArgSettings::Hidden) }; - if self.p.app.get_positionals().any(not_req_or_hidden) { + if self.app.get_positionals().any(not_req_or_hidden) { if let Some(args_tag) = self.get_args_tag(incl_reqs) { usage.push_str(&*args_tag); } else { @@ -104,7 +101,6 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { } if has_last && incl_reqs { let pos = self - .p .app .get_positionals() .find(|p| p.is_set(ArgSettings::Last)) @@ -113,7 +109,6 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { let req = pos.is_set(ArgSettings::Required); if req && self - .p .app .get_positionals() .any(|p| !p.is_set(ArgSettings::Required)) @@ -138,14 +133,15 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { } // incl_reqs is only false when this function is called recursively - if self.p.app.has_visible_subcommands() && incl_reqs - || self.p.is_set(AS::AllowExternalSubcommands) + if self.app.has_visible_subcommands() && incl_reqs + || self.app.is_set(AS::AllowExternalSubcommands) { - let placeholder = self.p.app.subcommand_value_name.unwrap_or("SUBCOMMAND"); - if self.p.is_set(AS::SubcommandsNegateReqs) || self.p.is_set(AS::ArgsNegateSubcommands) + let placeholder = self.app.subcommand_value_name.unwrap_or("SUBCOMMAND"); + if self.app.is_set(AS::SubcommandsNegateReqs) + || self.app.is_set(AS::ArgsNegateSubcommands) { usage.push_str("\n "); - if !self.p.is_set(AS::ArgsNegateSubcommands) { + if !self.app.is_set(AS::ArgsNegateSubcommands) { usage.push_str(&*self.create_help_usage(false)); } else { usage.push_str(&*name); @@ -153,8 +149,8 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { usage.push_str(" <"); usage.push_str(placeholder); usage.push('>'); - } else if self.p.is_set(AS::SubcommandRequired) - || self.p.is_set(AS::SubcommandRequiredElseHelp) + } else if self.app.is_set(AS::SubcommandRequired) + || self.app.is_set(AS::SubcommandRequiredElseHelp) { usage.push_str(" <"); usage.push_str(placeholder); @@ -183,17 +179,16 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { usage.push_str( &self - .p .app .usage .as_ref() - .or_else(|| self.p.app.bin_name.as_ref()) - .unwrap_or(&self.p.app.name)[..], + .or_else(|| self.app.bin_name.as_ref()) + .unwrap_or(&self.app.name)[..], ); usage.push_str(&*r_string); - if self.p.is_set(AS::SubcommandRequired) { + if self.app.is_set(AS::SubcommandRequired) { usage.push_str(" <"); - usage.push_str(self.p.app.subcommand_value_name.unwrap_or("SUBCOMMAND")); + usage.push_str(self.app.subcommand_value_name.unwrap_or("SUBCOMMAND")); usage.push('>'); } usage.shrink_to_fit(); @@ -205,7 +200,6 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { debug!("Usage::get_args_tag; incl_reqs = {:?}", incl_reqs); let mut count = 0; for pos in self - .p .app .get_positionals() .filter(|pos| !pos.is_set(ArgSettings::Required)) @@ -213,11 +207,10 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { .filter(|pos| !pos.is_set(ArgSettings::Last)) { debug!("Usage::get_args_tag:iter:{}", pos.name); - let required = self.p.app.groups_for_arg(&pos.id).any(|grp_s| { + let required = self.app.groups_for_arg(&pos.id).any(|grp_s| { debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s); // if it's part of a required group we don't want to count it - self.p - .app + self.app .groups .iter() .any(|g| g.required && (g.id == grp_s)) @@ -231,25 +224,23 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { } } - if !self.p.is_set(AS::DontCollapseArgsInUsage) && count > 1 { + if !self.app.is_set(AS::DontCollapseArgsInUsage) && count > 1 { debug!("Usage::get_args_tag:iter: More than one, returning [ARGS]"); // [ARGS] None } else if count == 1 && incl_reqs { let pos = self - .p .app .get_positionals() .find(|pos| { !pos.is_set(ArgSettings::Required) && !pos.is_set(ArgSettings::Hidden) && !pos.is_set(ArgSettings::Last) - && !self.p.app.groups_for_arg(&pos.id).any(|grp_s| { + && !self.app.groups_for_arg(&pos.id).any(|grp_s| { debug!("Usage::get_args_tag:iter:{:?}:iter:{:?}", pos.name, grp_s); // if it's part of a required group we don't want to count it - self.p - .app + self.app .groups .iter() .any(|g| g.required && (g.id == grp_s)) @@ -267,14 +258,13 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { pos.name_no_brackets(), pos.multiple_str() )) - } else if self.p.is_set(AS::DontCollapseArgsInUsage) - && self.p.app.has_positionals() + } else if self.app.is_set(AS::DontCollapseArgsInUsage) + && self.app.has_positionals() && incl_reqs { debug!("Usage::get_args_tag:iter: Don't collapse returning all"); Some( - self.p - .app + self.app .get_positionals() .filter(|pos| !pos.is_set(ArgSettings::Required)) .filter(|pos| !pos.is_set(ArgSettings::Hidden)) @@ -286,7 +276,6 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { } else if !incl_reqs { debug!("Usage::get_args_tag:iter: incl_reqs=false, building secondary usage string"); let highest_req_pos = self - .p .app .get_positionals() .filter_map(|pos| { @@ -297,10 +286,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { } }) .max() - .unwrap_or_else(|| Some(self.p.app.get_positionals().count())); + .unwrap_or_else(|| Some(self.app.get_positionals().count())); Some( - self.p - .app + self.app .get_positionals() .filter(|pos| pos.index <= highest_req_pos) .filter(|pos| !pos.is_set(ArgSettings::Required)) @@ -318,7 +306,7 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { // Determines if we need the `[OPTIONS]` tag in the usage string fn needs_options_tag(&self) -> bool { debug!("Usage::needs_options_tag"); - 'outer: for f in self.p.app.get_non_positionals() { + 'outer: for f in self.app.get_non_positionals() { debug!("Usage::needs_options_tag:iter: f={}", f.name); // Don't print `[OPTIONS]` just for help or version @@ -335,15 +323,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { debug!("Usage::needs_options_tag:iter Option is required"); continue; } - for grp_s in self.p.app.groups_for_arg(&f.id) { + for grp_s in self.app.groups_for_arg(&f.id) { debug!("Usage::needs_options_tag:iter:iter: grp_s={:?}", grp_s); - if self - .p - .app - .groups - .iter() - .any(|g| g.id == grp_s && g.required) - { + if self.app.groups.iter().any(|g| g.id == grp_s && g.required) { debug!("Usage::needs_options_tag:iter:iter: Group is required"); continue 'outer; } @@ -377,9 +359,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { let mut unrolled_reqs = IndexSet::new(); - for a in self.p.required.iter() { + for a in self.required.iter() { if let Some(m) = matcher { - for aa in self.p.app.unroll_requirements_for_arg(a, m) { + for aa in self.app.unroll_requirements_for_arg(a, m) { // if we don't check for duplicates here this causes duplicate error messages // see https://github.com/clap-rs/clap/issues/2770 unrolled_reqs.insert(aa); @@ -396,35 +378,33 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { ); let args_in_groups = self - .p .app .groups .iter() - .filter(|gn| self.p.required.contains(&gn.id)) - .flat_map(|g| self.p.app.unroll_args_in_group(&g.id)) + .filter(|gn| self.required.contains(&gn.id)) + .flat_map(|g| self.app.unroll_args_in_group(&g.id)) .collect::>(); for a in unrolled_reqs .iter() .chain(incls.iter()) - .filter(|name| !self.p.app.get_positionals().any(|p| &&p.id == name)) - .filter(|name| !self.p.app.groups.iter().any(|g| &&g.id == name)) + .filter(|name| !self.app.get_positionals().any(|p| &&p.id == name)) + .filter(|name| !self.app.groups.iter().any(|g| &&g.id == name)) .filter(|name| !args_in_groups.contains(name)) .filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name))) { debug!("Usage::get_required_usage_from:iter:{:?}", a); - let arg = self.p.app.find(a).expect(INTERNAL_ERROR_MSG).to_string(); + let arg = self.app.find(a).expect(INTERNAL_ERROR_MSG).to_string(); ret_val.push(arg); } let mut g_vec: Vec = vec![]; for g in unrolled_reqs .iter() - .filter(|n| self.p.app.groups.iter().any(|g| g.id == **n)) + .filter(|n| self.app.groups.iter().any(|g| g.id == **n)) { // don't print requirement for required groups that have an arg. if let Some(m) = matcher { let have_group_entry = self - .p .app .unroll_args_in_group(g) .iter() @@ -434,7 +414,7 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { } } - let elem = self.p.app.format_group(g); + let elem = self.app.format_group(g); if !g_vec.contains(&elem) { g_vec.push(elem); } @@ -444,9 +424,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { let mut pvec = unrolled_reqs .iter() .chain(incls.iter()) - .filter(|a| self.p.app.get_positionals().any(|p| &&p.id == a)) + .filter(|a| self.app.get_positionals().any(|p| &&p.id == a)) .filter(|&pos| matcher.map_or(true, |m| !m.contains(pos))) - .filter_map(|pos| self.p.app.find(pos)) + .filter_map(|pos| self.app.find(pos)) .filter(|&pos| incl_last || !pos.is_set(ArgSettings::Last)) .filter(|pos| !args_in_groups.contains(&pos.id)) .map(|pos| (pos.index.unwrap(), pos)) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 8c138845..2bdcc992 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -264,7 +264,7 @@ impl<'help, 'app> Parser<'help, 'app> { return Err(ClapError::no_equals( self.app, arg, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )); } ParseResult::NoMatchingArg { arg } => { @@ -279,7 +279,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, rest, arg, - Usage::new(self).create_usage_no_title(&used), + Usage::new(&self.app, &self.required).create_usage_no_title(&used), )) } ParseResult::HelpFlag => { @@ -353,7 +353,7 @@ impl<'help, 'app> Parser<'help, 'app> { return Err(ClapError::no_equals( self.app, arg, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )) } ParseResult::NoMatchingArg { arg } => { @@ -361,7 +361,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, arg, None, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )); } ParseResult::HelpFlag => { @@ -406,7 +406,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, arg_os.to_str_lossy().into_owned(), None, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )); } @@ -447,7 +447,7 @@ impl<'help, 'app> Parser<'help, 'app> { None => { return Err(ClapError::invalid_utf8( self.app, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )); } }; @@ -461,7 +461,7 @@ impl<'help, 'app> Parser<'help, 'app> { if !allow_invalid_utf8 && v.to_str().is_none() { return Err(ClapError::invalid_utf8( self.app, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )); } sc_m.add_val_to( @@ -506,7 +506,7 @@ impl<'help, 'app> Parser<'help, 'app> { return Err(ClapError::missing_subcommand( self.app, bn.to_string(), - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), )); } else if self.is_set(AS::SubcommandRequiredElseHelp) { debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true"); @@ -534,7 +534,7 @@ impl<'help, 'app> Parser<'help, 'app> { return ClapError::unnecessary_double_dash( self.app, arg_os.to_str_lossy().into_owned(), - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), ); } } @@ -555,7 +555,7 @@ impl<'help, 'app> Parser<'help, 'app> { .as_ref() .unwrap_or(&self.app.name) .to_string(), - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), ); } // If the argument must be a subcommand. @@ -574,7 +574,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, arg_os.to_str_lossy().into_owned(), None, - Usage::new(self).create_usage_with_title(&[]), + Usage::new(&self.app, &self.required).create_usage_with_title(&[]), ) } @@ -721,7 +721,8 @@ impl<'help, 'app> Parser<'help, 'app> { let mut mid_string = String::from(" "); if !self.is_set(AS::SubcommandsNegateReqs) { - let reqs = Usage::new(self).get_required_usage_from(&[], None, true); // maybe Some(m) + let reqs = + Usage::new(&self.app, &self.required).get_required_usage_from(&[], None, true); // maybe Some(m) for s in &reqs { mid_string.push_str(s); @@ -1563,7 +1564,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, format!("--{}", arg), did_you_mean, - Usage::new(self).create_usage_with_title(&*used), + Usage::new(&self.app, &self.required).create_usage_with_title(&*used), ) } diff --git a/src/parse/validator.rs b/src/parse/validator.rs index b95d04ea..16f17527 100644 --- a/src/parse/validator.rs +++ b/src/parse/validator.rs @@ -50,7 +50,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::empty_value( self.p.app, o, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -91,7 +91,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { ); return Err(Error::invalid_utf8( self.p.app, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } if !arg.possible_vals.is_empty() { @@ -122,7 +122,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { .filter_map(PossibleValue::get_visible_name) .collect::>(), arg, - Usage::new(self.p).create_usage_with_title(&used), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&used), )); } } @@ -134,7 +134,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::empty_value( self.p.app, arg, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } @@ -209,7 +209,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { self.p.app, arg, Vec::new(), - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )) }) } @@ -264,7 +264,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { .chain(used_filtered.iter()) .cloned() .collect(); - Usage::new(self.p).create_usage_with_title(&required) + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&required) } fn gather_requirements(&mut self, matcher: &ArgMatcher) { @@ -317,7 +317,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::unexpected_multiple_usage( self.p.app, a, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } if let Some(max_occurs) = a.max_occurs { @@ -332,7 +332,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { a, max_occurs, occurs, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -361,7 +361,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { } else { total_num }, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -378,7 +378,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { .expect(INVALID_UTF8) .to_string(), a.to_string(), - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -391,7 +391,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { a, num, ma.num_vals(), - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } num == 0 @@ -404,7 +404,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::empty_value( self.p.app, a, - Usage::new(self.p).create_usage_with_title(&[]), + Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), )); } Ok(()) @@ -514,7 +514,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { self.p.required ); - let usg = Usage::new(self.p); + let usg = Usage::new(&self.p.app, &self.p.required); let req_args = usg.get_required_usage_from(&incl, Some(matcher), true); From 232c17ebc46dfebe89aa5da76951849164c04615 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Feb 2022 13:23:58 -0600 Subject: [PATCH 2/5] refactor(help): Decouple from parser --- src/build/app/mod.rs | 20 ++++++----- src/output/help.rs | 84 +++++++++++++++++++------------------------- src/parse/parser.rs | 6 ++-- 3 files changed, 53 insertions(+), 57 deletions(-) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index 2e6bbc5f..4d8729df 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -678,9 +678,10 @@ impl<'help> App<'help> { self._build(); let color = self.get_color(); - let p = Parser::new(self); let mut c = Colorizer::new(false, color); - Help::new(HelpWriter::Buffer(&mut c), &p, false).write_help()?; + let parser = Parser::new(self); + let usage = Usage::new(&parser.app, &parser.required); + Help::new(HelpWriter::Buffer(&mut c), &parser.app, &usage, false).write_help()?; c.print() } @@ -703,9 +704,10 @@ impl<'help> App<'help> { self._build(); let color = self.get_color(); - let p = Parser::new(self); let mut c = Colorizer::new(false, color); - Help::new(HelpWriter::Buffer(&mut c), &p, true).write_help()?; + let parser = Parser::new(self); + let usage = Usage::new(&parser.app, &parser.required); + Help::new(HelpWriter::Buffer(&mut c), &parser.app, &usage, true).write_help()?; c.print() } @@ -728,8 +730,9 @@ impl<'help> App<'help> { pub fn write_help(&mut self, w: &mut W) -> io::Result<()> { self._build(); - let p = Parser::new(self); - Help::new(HelpWriter::Normal(w), &p, false).write_help()?; + let parser = Parser::new(self); + let usage = Usage::new(&parser.app, &parser.required); + Help::new(HelpWriter::Normal(w), &parser.app, &usage, false).write_help()?; w.flush() } @@ -752,8 +755,9 @@ impl<'help> App<'help> { pub fn write_long_help(&mut self, w: &mut W) -> io::Result<()> { self._build(); - let p = Parser::new(self); - Help::new(HelpWriter::Normal(w), &p, true).write_help()?; + let parser = Parser::new(self); + let usage = Usage::new(&parser.app, &parser.required); + Help::new(HelpWriter::Normal(w), &parser.app, &usage, true).write_help()?; w.flush() } diff --git a/src/output/help.rs b/src/output/help.rs index eefb5411..64501181 100644 --- a/src/output/help.rs +++ b/src/output/help.rs @@ -11,7 +11,6 @@ use std::{ use crate::{ build::{arg::display_arg_val, App, AppSettings, Arg, ArgSettings}, output::{fmt::Colorizer, Usage}, - parse::Parser, }; // Third party @@ -21,9 +20,10 @@ use textwrap::core::display_width; /// `clap` Help Writer. /// /// Wraps a writer stream providing different methods to generate help for `clap` objects. -pub(crate) struct Help<'help, 'app, 'parser, 'writer> { +pub(crate) struct Help<'help, 'app, 'writer> { writer: HelpWriter<'writer>, - parser: &'parser Parser<'help, 'app>, + app: &'app App<'help>, + usage: &'app Usage<'help, 'app>, next_line_help: bool, hide_pv: bool, term_w: usize, @@ -31,7 +31,7 @@ pub(crate) struct Help<'help, 'app, 'parser, 'writer> { } // Public Functions -impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { +impl<'help, 'app, 'writer> Help<'help, 'app, 'writer> { const DEFAULT_TEMPLATE: &'static str = "\ {before-help}{bin} {version}\n\ {author-with-newline}{about-with-newline}\n\ @@ -49,27 +49,29 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { /// Create a new `Help` instance. pub(crate) fn new( writer: HelpWriter<'writer>, - parser: &'parser Parser<'help, 'app>, + app: &'app App<'help>, + usage: &'app Usage<'help, 'app>, use_long: bool, ) -> Self { debug!("Help::new"); - let term_w = match parser.app.term_w { + let term_w = match app.term_w { Some(0) => usize::MAX, Some(w) => w, None => cmp::min( dimensions().map_or(100, |(w, _)| w), - match parser.app.max_w { + match app.max_w { None | Some(0) => usize::MAX, Some(mw) => mw, }, ), }; - let next_line_help = parser.is_set(AppSettings::NextLineHelp); - let hide_pv = parser.is_set(AppSettings::HidePossibleValues); + let next_line_help = app.is_set(AppSettings::NextLineHelp); + let hide_pv = app.is_set(AppSettings::HidePossibleValues); Help { writer, - parser, + app, + usage, next_line_help, hide_pv, term_w, @@ -81,22 +83,20 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { pub(crate) fn write_help(&mut self) -> io::Result<()> { debug!("Help::write_help"); - if let Some(h) = self.parser.app.help_str { + if let Some(h) = self.app.help_str { self.none(h)?; - } else if let Some(tmpl) = self.parser.app.template { + } else if let Some(tmpl) = self.app.template { self.write_templated_help(tmpl)?; } else { let pos = self - .parser .app .get_positionals() .any(|arg| should_show_arg(self.use_long, arg)); let non_pos = self - .parser .app .get_non_positionals() .any(|arg| should_show_arg(self.use_long, arg)); - let subcmds = self.parser.app.has_visible_subcommands(); + let subcmds = self.app.has_visible_subcommands(); if non_pos || pos || subcmds { self.write_templated_help(Self::DEFAULT_TEMPLATE)?; @@ -124,7 +124,7 @@ macro_rules! write_method { } // Methods to write Arg help. -impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { +impl<'help, 'app, 'writer> Help<'help, 'app, 'writer> { #[inline(never)] fn good + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { write_method!(self, msg, good) @@ -356,12 +356,9 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { fn write_before_help(&mut self) -> io::Result<()> { debug!("Help::write_before_help"); let before_help = if self.use_long { - self.parser - .app - .before_long_help - .or(self.parser.app.before_help) + self.app.before_long_help.or(self.app.before_help) } else { - self.parser.app.before_help + self.app.before_help }; if let Some(output) = before_help { self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w))?; @@ -373,12 +370,9 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { fn write_after_help(&mut self) -> io::Result<()> { debug!("Help::write_after_help"); let after_help = if self.use_long { - self.parser - .app - .after_long_help - .or(self.parser.app.after_help) + self.app.after_long_help.or(self.app.after_help) } else { - self.parser.app.after_help + self.app.after_help }; if let Some(output) = after_help { self.none("\n\n")?; @@ -618,9 +612,9 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { fn write_about(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> { let about = if self.use_long { - self.parser.app.long_about.or(self.parser.app.about) + self.app.long_about.or(self.app.about) } else { - self.parser.app.about + self.app.about }; if let Some(output) = about { if before_new_line { @@ -635,7 +629,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { } fn write_author(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> { - if let Some(author) = self.parser.app.author { + if let Some(author) = self.app.author { if before_new_line { self.none("\n")?; } @@ -648,7 +642,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { } fn write_version(&mut self) -> io::Result<()> { - let version = self.parser.app.version.or(self.parser.app.long_version); + let version = self.app.version.or(self.app.long_version); if let Some(output) = version { self.none(text_wrapper(output, self.term_w))?; } @@ -657,7 +651,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { } /// Methods to write a single subcommand -impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { +impl<'help, 'app, 'writer> Help<'help, 'app, 'writer> { fn write_subcommand( &mut self, sc_str: &str, @@ -731,27 +725,24 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { } // Methods to write Parser help. -impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { +impl<'help, 'app, 'writer> Help<'help, 'app, 'writer> { /// Writes help for all arguments (options, flags, args, subcommands) /// including titles of a Parser Object to the wrapped stream. pub(crate) fn write_all_args(&mut self) -> io::Result<()> { debug!("Help::write_all_args"); let pos = self - .parser .app .get_positionals_with_no_heading() .filter(|arg| should_show_arg(self.use_long, arg)) .collect::>(); let non_pos = self - .parser .app .get_non_positionals_with_no_heading() .filter(|arg| should_show_arg(self.use_long, arg)) .collect::>(); - let subcmds = self.parser.app.has_visible_subcommands(); + let subcmds = self.app.has_visible_subcommands(); let custom_headings = self - .parser .app .args .args() @@ -778,7 +769,6 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { if !custom_headings.is_empty() { for heading in custom_headings { let args = self - .parser .app .args .args() @@ -807,10 +797,10 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { self.none("\n\n")?; } - self.warning(self.parser.app.subcommand_heading.unwrap_or("SUBCOMMANDS"))?; + self.warning(self.app.subcommand_heading.unwrap_or("SUBCOMMANDS"))?; self.warning(":\n")?; - self.write_subcommands(self.parser.app)?; + self.write_subcommands(self.app)?; } Ok(()) @@ -871,15 +861,15 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { fn write_bin_name(&mut self) -> io::Result<()> { debug!("Help::write_bin_name"); - let bin_name = if let Some(bn) = self.parser.app.bin_name.as_ref() { + let bin_name = if let Some(bn) = self.app.bin_name.as_ref() { if bn.contains(' ') { // In case we're dealing with subcommands i.e. git mv is translated to git-mv bn.replace(' ', "-") } else { - text_wrapper(&self.parser.app.name.replace("{n}", "\n"), self.term_w) + text_wrapper(&self.app.name.replace("{n}", "\n"), self.term_w) } } else { - text_wrapper(&self.parser.app.name.replace("{n}", "\n"), self.term_w) + text_wrapper(&self.app.name.replace("{n}", "\n"), self.term_w) }; self.good(&bin_name)?; Ok(()) @@ -887,7 +877,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { } // Methods to write Parser help using templates. -impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { +impl<'help, 'app, 'writer> Help<'help, 'app, 'writer> { /// Write help to stream for the parser in the format defined by the template. /// /// For details about the template language see [`App::help_template`]. @@ -962,7 +952,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { self.warning("USAGE:")?; } "usage" => { - self.none(Usage::new(&self.parser.app, &self.parser.required).create_usage_no_title(&[]))?; + self.none(self.usage.create_usage_no_title(&[]))?; } "all-args" => { self.write_all_args()?; @@ -970,13 +960,13 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> { "options" => { // Include even those with a heading as we don't have a good way of // handling help_heading in the template. - self.write_args(&self.parser.app.get_non_positionals().collect::>())?; + self.write_args(&self.app.get_non_positionals().collect::>())?; } "positionals" => { - self.write_args(&self.parser.app.get_positionals().collect::>())?; + self.write_args(&self.app.get_positionals().collect::>())?; } "subcommands" => { - self.write_subcommands(self.parser.app)?; + self.write_subcommands(self.app)?; } "after-help" => { self.write_after_help()?; diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 2bdcc992..2bd22a29 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -1569,8 +1569,9 @@ impl<'help, 'app> Parser<'help, 'app> { } pub(crate) fn write_help_err(&self) -> ClapResult { + let usage = Usage::new(&self.app, &self.required); let mut c = Colorizer::new(true, self.color_help()); - Help::new(HelpWriter::Buffer(&mut c), self, false).write_help()?; + Help::new(HelpWriter::Buffer(&mut c), &self.app, &usage, false).write_help()?; Ok(c) } @@ -1581,9 +1582,10 @@ impl<'help, 'app> Parser<'help, 'app> { ); use_long = use_long && self.use_long_help(); + let usage = Usage::new(&self.app, &self.required); let mut c = Colorizer::new(false, self.color_help()); - match Help::new(HelpWriter::Buffer(&mut c), self, use_long).write_help() { + match Help::new(HelpWriter::Buffer(&mut c), &self.app, &usage, use_long).write_help() { Err(e) => e.into(), _ => ClapError::for_app(self.app, c, ErrorKind::DisplayHelp, vec![]), } From 05f8151d3d48766e7dbdb464abf1365550be0ac9 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Feb 2022 13:38:23 -0600 Subject: [PATCH 3/5] fix(usage): Track all required --- src/build/app/mod.rs | 3 +-- src/parse/parser.rs | 23 ++++++++--------------- 2 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index 4d8729df..ec32de1d 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -824,8 +824,7 @@ impl<'help> App<'help> { // before parsing incase we run into a subcommand self._build(); - let mut parser = Parser::new(self); - parser._build(); + let parser = Parser::new(self); Usage::new(&parser.app, &parser.required).create_usage_with_title(&[]) } } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 2bd22a29..110d8737 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -48,6 +48,14 @@ impl<'help, 'app> Parser<'help, 'app> { { reqs.insert(a.id.clone()); } + for group in &app.groups { + if group.required { + let idx = reqs.insert(group.id.clone()); + for a in &group.requires { + reqs.insert_child(idx, a.clone()); + } + } + } Parser { app, @@ -60,20 +68,6 @@ impl<'help, 'app> Parser<'help, 'app> { } } - // Does all the initializing and prepares the parser - pub(crate) fn _build(&mut self) { - debug!("Parser::_build"); - - for group in &self.app.groups { - if group.required { - let idx = self.required.insert(group.id.clone()); - for a in &group.requires { - self.required.insert_child(idx, a.clone()); - } - } - } - } - // Should we color the help? pub(crate) fn color_help(&self) -> ColorChoice { #[cfg(feature = "color")] @@ -96,7 +90,6 @@ impl<'help, 'app> Parser<'help, 'app> { ) -> ClapResult<()> { debug!("Parser::get_matches_with"); // Verify all positional assertions pass - self._build(); let mut subcmd_name: Option = None; let mut keep_state = false; From c638330e854ee2291a364ec5a5029dbcbe2084e2 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Feb 2022 13:44:55 -0600 Subject: [PATCH 4/5] refactor: Reduce what Parser visibility we can --- src/parse/parser.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 110d8737..8e7dd3b8 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -28,13 +28,13 @@ pub(crate) struct Parser<'help, 'app> { pub(crate) app: &'app mut App<'help>, pub(crate) required: ChildGraph, pub(crate) overridden: RefCell>, - pub(crate) seen: Vec, - pub(crate) cur_idx: Cell, + seen: Vec, + cur_idx: Cell, /// Index of the previous flag subcommand in a group of flags. - pub(crate) flag_subcmd_at: Option, + flag_subcmd_at: Option, /// Counter indicating the number of items to skip /// when revisiting the group of flags which includes the flag subcommand. - pub(crate) flag_subcmd_skip: usize, + flag_subcmd_skip: usize, } // Initializing Methods From 3722270e4741e92cfd69d898d83a1a52a2690330 Mon Sep 17 00:00:00 2001 From: Ed Page Date: Tue, 1 Feb 2022 13:56:45 -0600 Subject: [PATCH 5/5] style: Clippy --- src/build/app/mod.rs | 18 +++++++++--------- src/parse/parser.rs | 34 +++++++++++++++++----------------- src/parse/validator.rs | 26 +++++++++++++------------- 3 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/build/app/mod.rs b/src/build/app/mod.rs index ec32de1d..ab811f0e 100644 --- a/src/build/app/mod.rs +++ b/src/build/app/mod.rs @@ -680,8 +680,8 @@ impl<'help> App<'help> { let mut c = Colorizer::new(false, color); let parser = Parser::new(self); - let usage = Usage::new(&parser.app, &parser.required); - Help::new(HelpWriter::Buffer(&mut c), &parser.app, &usage, false).write_help()?; + let usage = Usage::new(parser.app, &parser.required); + Help::new(HelpWriter::Buffer(&mut c), parser.app, &usage, false).write_help()?; c.print() } @@ -706,8 +706,8 @@ impl<'help> App<'help> { let mut c = Colorizer::new(false, color); let parser = Parser::new(self); - let usage = Usage::new(&parser.app, &parser.required); - Help::new(HelpWriter::Buffer(&mut c), &parser.app, &usage, true).write_help()?; + let usage = Usage::new(parser.app, &parser.required); + Help::new(HelpWriter::Buffer(&mut c), parser.app, &usage, true).write_help()?; c.print() } @@ -731,8 +731,8 @@ impl<'help> App<'help> { self._build(); let parser = Parser::new(self); - let usage = Usage::new(&parser.app, &parser.required); - Help::new(HelpWriter::Normal(w), &parser.app, &usage, false).write_help()?; + let usage = Usage::new(parser.app, &parser.required); + Help::new(HelpWriter::Normal(w), parser.app, &usage, false).write_help()?; w.flush() } @@ -756,8 +756,8 @@ impl<'help> App<'help> { self._build(); let parser = Parser::new(self); - let usage = Usage::new(&parser.app, &parser.required); - Help::new(HelpWriter::Normal(w), &parser.app, &usage, true).write_help()?; + let usage = Usage::new(parser.app, &parser.required); + Help::new(HelpWriter::Normal(w), parser.app, &usage, true).write_help()?; w.flush() } @@ -825,7 +825,7 @@ impl<'help> App<'help> { self._build(); let parser = Parser::new(self); - Usage::new(&parser.app, &parser.required).create_usage_with_title(&[]) + Usage::new(parser.app, &parser.required).create_usage_with_title(&[]) } } diff --git a/src/parse/parser.rs b/src/parse/parser.rs index 8e7dd3b8..d9d17dbb 100644 --- a/src/parse/parser.rs +++ b/src/parse/parser.rs @@ -257,7 +257,7 @@ impl<'help, 'app> Parser<'help, 'app> { return Err(ClapError::no_equals( self.app, arg, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )); } ParseResult::NoMatchingArg { arg } => { @@ -272,7 +272,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, rest, arg, - Usage::new(&self.app, &self.required).create_usage_no_title(&used), + Usage::new(self.app, &self.required).create_usage_no_title(&used), )) } ParseResult::HelpFlag => { @@ -346,7 +346,7 @@ impl<'help, 'app> Parser<'help, 'app> { return Err(ClapError::no_equals( self.app, arg, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )) } ParseResult::NoMatchingArg { arg } => { @@ -354,7 +354,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, arg, None, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )); } ParseResult::HelpFlag => { @@ -399,7 +399,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, arg_os.to_str_lossy().into_owned(), None, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )); } @@ -440,7 +440,7 @@ impl<'help, 'app> Parser<'help, 'app> { None => { return Err(ClapError::invalid_utf8( self.app, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )); } }; @@ -454,7 +454,7 @@ impl<'help, 'app> Parser<'help, 'app> { if !allow_invalid_utf8 && v.to_str().is_none() { return Err(ClapError::invalid_utf8( self.app, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )); } sc_m.add_val_to( @@ -499,7 +499,7 @@ impl<'help, 'app> Parser<'help, 'app> { return Err(ClapError::missing_subcommand( self.app, bn.to_string(), - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), )); } else if self.is_set(AS::SubcommandRequiredElseHelp) { debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true"); @@ -527,7 +527,7 @@ impl<'help, 'app> Parser<'help, 'app> { return ClapError::unnecessary_double_dash( self.app, arg_os.to_str_lossy().into_owned(), - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), ); } } @@ -548,7 +548,7 @@ impl<'help, 'app> Parser<'help, 'app> { .as_ref() .unwrap_or(&self.app.name) .to_string(), - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), ); } // If the argument must be a subcommand. @@ -567,7 +567,7 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, arg_os.to_str_lossy().into_owned(), None, - Usage::new(&self.app, &self.required).create_usage_with_title(&[]), + Usage::new(self.app, &self.required).create_usage_with_title(&[]), ) } @@ -715,7 +715,7 @@ impl<'help, 'app> Parser<'help, 'app> { if !self.is_set(AS::SubcommandsNegateReqs) { let reqs = - Usage::new(&self.app, &self.required).get_required_usage_from(&[], None, true); // maybe Some(m) + Usage::new(self.app, &self.required).get_required_usage_from(&[], None, true); // maybe Some(m) for s in &reqs { mid_string.push_str(s); @@ -1557,14 +1557,14 @@ impl<'help, 'app> Parser<'help, 'app> { self.app, format!("--{}", arg), did_you_mean, - Usage::new(&self.app, &self.required).create_usage_with_title(&*used), + Usage::new(self.app, &self.required).create_usage_with_title(&*used), ) } pub(crate) fn write_help_err(&self) -> ClapResult { - let usage = Usage::new(&self.app, &self.required); + let usage = Usage::new(self.app, &self.required); let mut c = Colorizer::new(true, self.color_help()); - Help::new(HelpWriter::Buffer(&mut c), &self.app, &usage, false).write_help()?; + Help::new(HelpWriter::Buffer(&mut c), self.app, &usage, false).write_help()?; Ok(c) } @@ -1575,10 +1575,10 @@ impl<'help, 'app> Parser<'help, 'app> { ); use_long = use_long && self.use_long_help(); - let usage = Usage::new(&self.app, &self.required); + let usage = Usage::new(self.app, &self.required); let mut c = Colorizer::new(false, self.color_help()); - match Help::new(HelpWriter::Buffer(&mut c), &self.app, &usage, use_long).write_help() { + match Help::new(HelpWriter::Buffer(&mut c), self.app, &usage, use_long).write_help() { Err(e) => e.into(), _ => ClapError::for_app(self.app, c, ErrorKind::DisplayHelp, vec![]), } diff --git a/src/parse/validator.rs b/src/parse/validator.rs index 16f17527..853be564 100644 --- a/src/parse/validator.rs +++ b/src/parse/validator.rs @@ -50,7 +50,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::empty_value( self.p.app, o, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -91,7 +91,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { ); return Err(Error::invalid_utf8( self.p.app, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } if !arg.possible_vals.is_empty() { @@ -122,7 +122,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { .filter_map(PossibleValue::get_visible_name) .collect::>(), arg, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&used), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&used), )); } } @@ -134,7 +134,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::empty_value( self.p.app, arg, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } @@ -209,7 +209,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { self.p.app, arg, Vec::new(), - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )) }) } @@ -264,7 +264,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { .chain(used_filtered.iter()) .cloned() .collect(); - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&required) + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&required) } fn gather_requirements(&mut self, matcher: &ArgMatcher) { @@ -317,7 +317,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::unexpected_multiple_usage( self.p.app, a, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } if let Some(max_occurs) = a.max_occurs { @@ -332,7 +332,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { a, max_occurs, occurs, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -361,7 +361,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { } else { total_num }, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -378,7 +378,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { .expect(INVALID_UTF8) .to_string(), a.to_string(), - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } } @@ -391,7 +391,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { a, num, ma.num_vals(), - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } num == 0 @@ -404,7 +404,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { return Err(Error::empty_value( self.p.app, a, - Usage::new(&self.p.app, &self.p.required).create_usage_with_title(&[]), + Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]), )); } Ok(()) @@ -514,7 +514,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> { self.p.required ); - let usg = Usage::new(&self.p.app, &self.p.required); + let usg = Usage::new(self.p.app, &self.p.required); let req_args = usg.get_required_usage_from(&incl, Some(matcher), true);