Merge pull request #3381 from epage/parser

refactor: Minor progress on reducing Parser's visibility
This commit is contained in:
Ed Page 2022-02-01 14:21:09 -06:00 committed by GitHub
commit 8efee8a671
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 146 additions and 177 deletions

View file

@ -678,9 +678,10 @@ impl<'help> App<'help> {
self._build(); self._build();
let color = self.get_color(); let color = self.get_color();
let p = Parser::new(self);
let mut c = Colorizer::new(false, color); 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() c.print()
} }
@ -703,9 +704,10 @@ impl<'help> App<'help> {
self._build(); self._build();
let color = self.get_color(); let color = self.get_color();
let p = Parser::new(self);
let mut c = Colorizer::new(false, color); 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() c.print()
} }
@ -728,8 +730,9 @@ impl<'help> App<'help> {
pub fn write_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> { pub fn write_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
self._build(); self._build();
let p = Parser::new(self); let parser = Parser::new(self);
Help::new(HelpWriter::Normal(w), &p, false).write_help()?; let usage = Usage::new(parser.app, &parser.required);
Help::new(HelpWriter::Normal(w), parser.app, &usage, false).write_help()?;
w.flush() w.flush()
} }
@ -752,8 +755,9 @@ impl<'help> App<'help> {
pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> { pub fn write_long_help<W: Write>(&mut self, w: &mut W) -> io::Result<()> {
self._build(); self._build();
let p = Parser::new(self); let parser = Parser::new(self);
Help::new(HelpWriter::Normal(w), &p, true).write_help()?; let usage = Usage::new(parser.app, &parser.required);
Help::new(HelpWriter::Normal(w), parser.app, &usage, true).write_help()?;
w.flush() w.flush()
} }
@ -820,9 +824,8 @@ impl<'help> App<'help> {
// before parsing incase we run into a subcommand // before parsing incase we run into a subcommand
self._build(); self._build();
let mut parser = Parser::new(self); let parser = Parser::new(self);
parser._build(); Usage::new(parser.app, &parser.required).create_usage_with_title(&[])
Usage::new(&parser).create_usage_with_title(&[])
} }
} }

View file

@ -11,7 +11,6 @@ use std::{
use crate::{ use crate::{
build::{arg::display_arg_val, App, AppSettings, Arg, ArgSettings}, build::{arg::display_arg_val, App, AppSettings, Arg, ArgSettings},
output::{fmt::Colorizer, Usage}, output::{fmt::Colorizer, Usage},
parse::Parser,
}; };
// Third party // Third party
@ -21,9 +20,10 @@ use textwrap::core::display_width;
/// `clap` Help Writer. /// `clap` Help Writer.
/// ///
/// Wraps a writer stream providing different methods to generate help for `clap` objects. /// 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>, writer: HelpWriter<'writer>,
parser: &'parser Parser<'help, 'app>, app: &'app App<'help>,
usage: &'app Usage<'help, 'app>,
next_line_help: bool, next_line_help: bool,
hide_pv: bool, hide_pv: bool,
term_w: usize, term_w: usize,
@ -31,7 +31,7 @@ pub(crate) struct Help<'help, 'app, 'parser, 'writer> {
} }
// Public Functions // 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 = "\ const DEFAULT_TEMPLATE: &'static str = "\
{before-help}{bin} {version}\n\ {before-help}{bin} {version}\n\
{author-with-newline}{about-with-newline}\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. /// Create a new `Help` instance.
pub(crate) fn new( pub(crate) fn new(
writer: HelpWriter<'writer>, writer: HelpWriter<'writer>,
parser: &'parser Parser<'help, 'app>, app: &'app App<'help>,
usage: &'app Usage<'help, 'app>,
use_long: bool, use_long: bool,
) -> Self { ) -> Self {
debug!("Help::new"); debug!("Help::new");
let term_w = match parser.app.term_w { let term_w = match app.term_w {
Some(0) => usize::MAX, Some(0) => usize::MAX,
Some(w) => w, Some(w) => w,
None => cmp::min( None => cmp::min(
dimensions().map_or(100, |(w, _)| w), dimensions().map_or(100, |(w, _)| w),
match parser.app.max_w { match app.max_w {
None | Some(0) => usize::MAX, None | Some(0) => usize::MAX,
Some(mw) => mw, Some(mw) => mw,
}, },
), ),
}; };
let next_line_help = parser.is_set(AppSettings::NextLineHelp); let next_line_help = app.is_set(AppSettings::NextLineHelp);
let hide_pv = parser.is_set(AppSettings::HidePossibleValues); let hide_pv = app.is_set(AppSettings::HidePossibleValues);
Help { Help {
writer, writer,
parser, app,
usage,
next_line_help, next_line_help,
hide_pv, hide_pv,
term_w, 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<()> { pub(crate) fn write_help(&mut self) -> io::Result<()> {
debug!("Help::write_help"); debug!("Help::write_help");
if let Some(h) = self.parser.app.help_str { if let Some(h) = self.app.help_str {
self.none(h)?; 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)?; self.write_templated_help(tmpl)?;
} else { } else {
let pos = self let pos = self
.parser
.app .app
.get_positionals() .get_positionals()
.any(|arg| should_show_arg(self.use_long, arg)); .any(|arg| should_show_arg(self.use_long, arg));
let non_pos = self let non_pos = self
.parser
.app .app
.get_non_positionals() .get_non_positionals()
.any(|arg| should_show_arg(self.use_long, arg)); .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 { if non_pos || pos || subcmds {
self.write_templated_help(Self::DEFAULT_TEMPLATE)?; self.write_templated_help(Self::DEFAULT_TEMPLATE)?;
@ -124,7 +124,7 @@ macro_rules! write_method {
} }
// Methods to write Arg help. // 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)] #[inline(never)]
fn good<T: Into<String> + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> { fn good<T: Into<String> + AsRef<[u8]>>(&mut self, msg: T) -> io::Result<()> {
write_method!(self, msg, good) 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<()> { fn write_before_help(&mut self) -> io::Result<()> {
debug!("Help::write_before_help"); debug!("Help::write_before_help");
let before_help = if self.use_long { let before_help = if self.use_long {
self.parser self.app.before_long_help.or(self.app.before_help)
.app
.before_long_help
.or(self.parser.app.before_help)
} else { } else {
self.parser.app.before_help self.app.before_help
}; };
if let Some(output) = before_help { if let Some(output) = before_help {
self.none(text_wrapper(&output.replace("{n}", "\n"), self.term_w))?; 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<()> { fn write_after_help(&mut self) -> io::Result<()> {
debug!("Help::write_after_help"); debug!("Help::write_after_help");
let after_help = if self.use_long { let after_help = if self.use_long {
self.parser self.app.after_long_help.or(self.app.after_help)
.app
.after_long_help
.or(self.parser.app.after_help)
} else { } else {
self.parser.app.after_help self.app.after_help
}; };
if let Some(output) = after_help { if let Some(output) = after_help {
self.none("\n\n")?; 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<()> { fn write_about(&mut self, before_new_line: bool, after_new_line: bool) -> io::Result<()> {
let about = if self.use_long { 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 { } else {
self.parser.app.about self.app.about
}; };
if let Some(output) = about { if let Some(output) = about {
if before_new_line { 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<()> { 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 { if before_new_line {
self.none("\n")?; self.none("\n")?;
} }
@ -648,7 +642,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
} }
fn write_version(&mut self) -> io::Result<()> { 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 { if let Some(output) = version {
self.none(text_wrapper(output, self.term_w))?; 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 /// 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( fn write_subcommand(
&mut self, &mut self,
sc_str: &str, sc_str: &str,
@ -731,27 +725,24 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
} }
// Methods to write Parser help. // 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) /// Writes help for all arguments (options, flags, args, subcommands)
/// including titles of a Parser Object to the wrapped stream. /// including titles of a Parser Object to the wrapped stream.
pub(crate) fn write_all_args(&mut self) -> io::Result<()> { pub(crate) fn write_all_args(&mut self) -> io::Result<()> {
debug!("Help::write_all_args"); debug!("Help::write_all_args");
let pos = self let pos = self
.parser
.app .app
.get_positionals_with_no_heading() .get_positionals_with_no_heading()
.filter(|arg| should_show_arg(self.use_long, arg)) .filter(|arg| should_show_arg(self.use_long, arg))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let non_pos = self let non_pos = self
.parser
.app .app
.get_non_positionals_with_no_heading() .get_non_positionals_with_no_heading()
.filter(|arg| should_show_arg(self.use_long, arg)) .filter(|arg| should_show_arg(self.use_long, arg))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let subcmds = self.parser.app.has_visible_subcommands(); let subcmds = self.app.has_visible_subcommands();
let custom_headings = self let custom_headings = self
.parser
.app .app
.args .args
.args() .args()
@ -778,7 +769,6 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
if !custom_headings.is_empty() { if !custom_headings.is_empty() {
for heading in custom_headings { for heading in custom_headings {
let args = self let args = self
.parser
.app .app
.args .args
.args() .args()
@ -807,10 +797,10 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
self.none("\n\n")?; 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.warning(":\n")?;
self.write_subcommands(self.parser.app)?; self.write_subcommands(self.app)?;
} }
Ok(()) Ok(())
@ -871,15 +861,15 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
fn write_bin_name(&mut self) -> io::Result<()> { fn write_bin_name(&mut self) -> io::Result<()> {
debug!("Help::write_bin_name"); 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(' ') { if bn.contains(' ') {
// In case we're dealing with subcommands i.e. git mv is translated to git-mv // In case we're dealing with subcommands i.e. git mv is translated to git-mv
bn.replace(' ', "-") bn.replace(' ', "-")
} else { } 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 { } 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)?; self.good(&bin_name)?;
Ok(()) Ok(())
@ -887,7 +877,7 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
} }
// Methods to write Parser help using templates. // 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. /// Write help to stream for the parser in the format defined by the template.
/// ///
/// For details about the template language see [`App::help_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:")?; self.warning("USAGE:")?;
} }
"usage" => { "usage" => {
self.none(Usage::new(self.parser).create_usage_no_title(&[]))?; self.none(self.usage.create_usage_no_title(&[]))?;
} }
"all-args" => { "all-args" => {
self.write_all_args()?; self.write_all_args()?;
@ -970,13 +960,13 @@ impl<'help, 'app, 'parser, 'writer> Help<'help, 'app, 'parser, 'writer> {
"options" => { "options" => {
// Include even those with a heading as we don't have a good way of // Include even those with a heading as we don't have a good way of
// handling help_heading in the template. // handling help_heading in the template.
self.write_args(&self.parser.app.get_non_positionals().collect::<Vec<_>>())?; self.write_args(&self.app.get_non_positionals().collect::<Vec<_>>())?;
} }
"positionals" => { "positionals" => {
self.write_args(&self.parser.app.get_positionals().collect::<Vec<_>>())?; self.write_args(&self.app.get_positionals().collect::<Vec<_>>())?;
} }
"subcommands" => { "subcommands" => {
self.write_subcommands(self.parser.app)?; self.write_subcommands(self.app)?;
} }
"after-help" => { "after-help" => {
self.write_after_help()?; self.write_after_help()?;

View file

@ -3,19 +3,20 @@ use indexmap::IndexSet;
// Internal // Internal
use crate::{ use crate::{
build::AppSettings as AS, build::AppSettings as AS,
build::{Arg, ArgSettings}, build::{App, Arg, ArgSettings},
parse::{ArgMatcher, Parser}, parse::ArgMatcher,
util::Id, util::{ChildGraph, Id},
INTERNAL_ERROR_MSG, INTERNAL_ERROR_MSG,
}; };
pub(crate) struct Usage<'help, 'app, 'parser> { pub(crate) struct Usage<'help, 'app> {
p: &'parser Parser<'help, 'app>, app: &'app App<'help>,
required: &'app ChildGraph<Id>,
} }
impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> { impl<'help, 'app> Usage<'help, 'app> {
pub(crate) fn new(p: &'parser Parser<'help, 'app>) -> Self { pub(crate) fn new(app: &'app App<'help>, required: &'app ChildGraph<Id>) -> Self {
Usage { p } Usage { app, required }
} }
// Creates a usage string for display. This happens just after all arguments were parsed, but before // 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. // 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 { pub(crate) fn create_usage_no_title(&self, used: &[Id]) -> String {
debug!("Usage::create_usage_no_title"); 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) String::from(&*u)
} else if used.is_empty() { } else if used.is_empty() {
self.create_help_usage(true) 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); debug!("Usage::create_help_usage; incl_reqs={:?}", incl_reqs);
let mut usage = String::with_capacity(75); let mut usage = String::with_capacity(75);
let name = self let name = self
.p
.app .app
.usage .usage
.as_ref() .as_ref()
.or_else(|| self.p.app.bin_name.as_ref()) .or_else(|| self.app.bin_name.as_ref())
.unwrap_or(&self.p.app.name); .unwrap_or(&self.app.name);
usage.push_str(&*name); usage.push_str(&*name);
let req_string = if incl_reqs { let req_string = if incl_reqs {
self.get_required_usage_from(&[], None, false) self.get_required_usage_from(&[], None, false)
@ -64,30 +64,27 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
usage.push_str(" [OPTIONS]"); 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 { if !allow_missing_positional {
usage.push_str(&req_string); usage.push_str(&req_string);
} }
let has_last = self let has_last = self
.p
.app .app
.get_positionals() .get_positionals()
.any(|p| p.is_set(ArgSettings::Last)); .any(|p| p.is_set(ArgSettings::Last));
// places a '--' in the usage string if there are args and options // places a '--' in the usage string if there are args and options
// supporting multiple values // supporting multiple values
if self if self
.p
.app .app
.get_non_positionals() .get_non_positionals()
.any(|o| o.is_set(ArgSettings::MultipleValues)) .any(|o| o.is_set(ArgSettings::MultipleValues))
&& self && self
.p
.app .app
.get_positionals() .get_positionals()
.any(|p| !p.is_set(ArgSettings::Required)) .any(|p| !p.is_set(ArgSettings::Required))
&& !(self.p.app.has_visible_subcommands() && !(self.app.has_visible_subcommands()
|| self.p.is_set(AS::AllowExternalSubcommands)) || self.app.is_set(AS::AllowExternalSubcommands))
&& !has_last && !has_last
{ {
usage.push_str(" [--]"); 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::Required) || p.is_set(ArgSettings::Last))
&& !p.is_set(ArgSettings::Hidden) && !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) { if let Some(args_tag) = self.get_args_tag(incl_reqs) {
usage.push_str(&*args_tag); usage.push_str(&*args_tag);
} else { } else {
@ -104,7 +101,6 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
} }
if has_last && incl_reqs { if has_last && incl_reqs {
let pos = self let pos = self
.p
.app .app
.get_positionals() .get_positionals()
.find(|p| p.is_set(ArgSettings::Last)) .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); let req = pos.is_set(ArgSettings::Required);
if req if req
&& self && self
.p
.app .app
.get_positionals() .get_positionals()
.any(|p| !p.is_set(ArgSettings::Required)) .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 // incl_reqs is only false when this function is called recursively
if self.p.app.has_visible_subcommands() && incl_reqs if self.app.has_visible_subcommands() && incl_reqs
|| self.p.is_set(AS::AllowExternalSubcommands) || self.app.is_set(AS::AllowExternalSubcommands)
{ {
let placeholder = self.p.app.subcommand_value_name.unwrap_or("SUBCOMMAND"); let placeholder = self.app.subcommand_value_name.unwrap_or("SUBCOMMAND");
if self.p.is_set(AS::SubcommandsNegateReqs) || self.p.is_set(AS::ArgsNegateSubcommands) if self.app.is_set(AS::SubcommandsNegateReqs)
|| self.app.is_set(AS::ArgsNegateSubcommands)
{ {
usage.push_str("\n "); 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)); usage.push_str(&*self.create_help_usage(false));
} else { } else {
usage.push_str(&*name); usage.push_str(&*name);
@ -153,8 +149,8 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
usage.push_str(" <"); usage.push_str(" <");
usage.push_str(placeholder); usage.push_str(placeholder);
usage.push('>'); usage.push('>');
} else if self.p.is_set(AS::SubcommandRequired) } else if self.app.is_set(AS::SubcommandRequired)
|| self.p.is_set(AS::SubcommandRequiredElseHelp) || self.app.is_set(AS::SubcommandRequiredElseHelp)
{ {
usage.push_str(" <"); usage.push_str(" <");
usage.push_str(placeholder); usage.push_str(placeholder);
@ -183,17 +179,16 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
usage.push_str( usage.push_str(
&self &self
.p
.app .app
.usage .usage
.as_ref() .as_ref()
.or_else(|| self.p.app.bin_name.as_ref()) .or_else(|| self.app.bin_name.as_ref())
.unwrap_or(&self.p.app.name)[..], .unwrap_or(&self.app.name)[..],
); );
usage.push_str(&*r_string); 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(" <");
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.push('>');
} }
usage.shrink_to_fit(); 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); debug!("Usage::get_args_tag; incl_reqs = {:?}", incl_reqs);
let mut count = 0; let mut count = 0;
for pos in self for pos in self
.p
.app .app
.get_positionals() .get_positionals()
.filter(|pos| !pos.is_set(ArgSettings::Required)) .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)) .filter(|pos| !pos.is_set(ArgSettings::Last))
{ {
debug!("Usage::get_args_tag:iter:{}", pos.name); 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); 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 // if it's part of a required group we don't want to count it
self.p self.app
.app
.groups .groups
.iter() .iter()
.any(|g| g.required && (g.id == grp_s)) .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]"); debug!("Usage::get_args_tag:iter: More than one, returning [ARGS]");
// [ARGS] // [ARGS]
None None
} else if count == 1 && incl_reqs { } else if count == 1 && incl_reqs {
let pos = self let pos = self
.p
.app .app
.get_positionals() .get_positionals()
.find(|pos| { .find(|pos| {
!pos.is_set(ArgSettings::Required) !pos.is_set(ArgSettings::Required)
&& !pos.is_set(ArgSettings::Hidden) && !pos.is_set(ArgSettings::Hidden)
&& !pos.is_set(ArgSettings::Last) && !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); 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 // if it's part of a required group we don't want to count it
self.p self.app
.app
.groups .groups
.iter() .iter()
.any(|g| g.required && (g.id == grp_s)) .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.name_no_brackets(),
pos.multiple_str() pos.multiple_str()
)) ))
} else if self.p.is_set(AS::DontCollapseArgsInUsage) } else if self.app.is_set(AS::DontCollapseArgsInUsage)
&& self.p.app.has_positionals() && self.app.has_positionals()
&& incl_reqs && incl_reqs
{ {
debug!("Usage::get_args_tag:iter: Don't collapse returning all"); debug!("Usage::get_args_tag:iter: Don't collapse returning all");
Some( Some(
self.p self.app
.app
.get_positionals() .get_positionals()
.filter(|pos| !pos.is_set(ArgSettings::Required)) .filter(|pos| !pos.is_set(ArgSettings::Required))
.filter(|pos| !pos.is_set(ArgSettings::Hidden)) .filter(|pos| !pos.is_set(ArgSettings::Hidden))
@ -286,7 +276,6 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
} else if !incl_reqs { } else if !incl_reqs {
debug!("Usage::get_args_tag:iter: incl_reqs=false, building secondary usage string"); debug!("Usage::get_args_tag:iter: incl_reqs=false, building secondary usage string");
let highest_req_pos = self let highest_req_pos = self
.p
.app .app
.get_positionals() .get_positionals()
.filter_map(|pos| { .filter_map(|pos| {
@ -297,10 +286,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
} }
}) })
.max() .max()
.unwrap_or_else(|| Some(self.p.app.get_positionals().count())); .unwrap_or_else(|| Some(self.app.get_positionals().count()));
Some( Some(
self.p self.app
.app
.get_positionals() .get_positionals()
.filter(|pos| pos.index <= highest_req_pos) .filter(|pos| pos.index <= highest_req_pos)
.filter(|pos| !pos.is_set(ArgSettings::Required)) .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 // Determines if we need the `[OPTIONS]` tag in the usage string
fn needs_options_tag(&self) -> bool { fn needs_options_tag(&self) -> bool {
debug!("Usage::needs_options_tag"); 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); debug!("Usage::needs_options_tag:iter: f={}", f.name);
// Don't print `[OPTIONS]` just for help or version // 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"); debug!("Usage::needs_options_tag:iter Option is required");
continue; 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); debug!("Usage::needs_options_tag:iter:iter: grp_s={:?}", grp_s);
if self if self.app.groups.iter().any(|g| g.id == grp_s && g.required) {
.p
.app
.groups
.iter()
.any(|g| g.id == grp_s && g.required)
{
debug!("Usage::needs_options_tag:iter:iter: Group is required"); debug!("Usage::needs_options_tag:iter:iter: Group is required");
continue 'outer; continue 'outer;
} }
@ -377,9 +359,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
let mut unrolled_reqs = IndexSet::new(); let mut unrolled_reqs = IndexSet::new();
for a in self.p.required.iter() { for a in self.required.iter() {
if let Some(m) = matcher { 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 // if we don't check for duplicates here this causes duplicate error messages
// see https://github.com/clap-rs/clap/issues/2770 // see https://github.com/clap-rs/clap/issues/2770
unrolled_reqs.insert(aa); unrolled_reqs.insert(aa);
@ -396,35 +378,33 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
); );
let args_in_groups = self let args_in_groups = self
.p
.app .app
.groups .groups
.iter() .iter()
.filter(|gn| self.p.required.contains(&gn.id)) .filter(|gn| self.required.contains(&gn.id))
.flat_map(|g| self.p.app.unroll_args_in_group(&g.id)) .flat_map(|g| self.app.unroll_args_in_group(&g.id))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
for a in unrolled_reqs for a in unrolled_reqs
.iter() .iter()
.chain(incls.iter()) .chain(incls.iter())
.filter(|name| !self.p.app.get_positionals().any(|p| &&p.id == name)) .filter(|name| !self.app.get_positionals().any(|p| &&p.id == name))
.filter(|name| !self.p.app.groups.iter().any(|g| &&g.id == name)) .filter(|name| !self.app.groups.iter().any(|g| &&g.id == name))
.filter(|name| !args_in_groups.contains(name)) .filter(|name| !args_in_groups.contains(name))
.filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name))) .filter(|name| !(matcher.is_some() && matcher.as_ref().unwrap().contains(name)))
{ {
debug!("Usage::get_required_usage_from:iter:{:?}", a); 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); ret_val.push(arg);
} }
let mut g_vec: Vec<String> = vec![]; let mut g_vec: Vec<String> = vec![];
for g in unrolled_reqs for g in unrolled_reqs
.iter() .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. // don't print requirement for required groups that have an arg.
if let Some(m) = matcher { if let Some(m) = matcher {
let have_group_entry = self let have_group_entry = self
.p
.app .app
.unroll_args_in_group(g) .unroll_args_in_group(g)
.iter() .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) { if !g_vec.contains(&elem) {
g_vec.push(elem); g_vec.push(elem);
} }
@ -444,9 +424,9 @@ impl<'help, 'app, 'parser> Usage<'help, 'app, 'parser> {
let mut pvec = unrolled_reqs let mut pvec = unrolled_reqs
.iter() .iter()
.chain(incls.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(|&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| incl_last || !pos.is_set(ArgSettings::Last))
.filter(|pos| !args_in_groups.contains(&pos.id)) .filter(|pos| !args_in_groups.contains(&pos.id))
.map(|pos| (pos.index.unwrap(), pos)) .map(|pos| (pos.index.unwrap(), pos))

View file

@ -28,13 +28,13 @@ pub(crate) struct Parser<'help, 'app> {
pub(crate) app: &'app mut App<'help>, pub(crate) app: &'app mut App<'help>,
pub(crate) required: ChildGraph<Id>, pub(crate) required: ChildGraph<Id>,
pub(crate) overridden: RefCell<Vec<Id>>, pub(crate) overridden: RefCell<Vec<Id>>,
pub(crate) seen: Vec<Id>, seen: Vec<Id>,
pub(crate) cur_idx: Cell<usize>, cur_idx: Cell<usize>,
/// Index of the previous flag subcommand in a group of flags. /// Index of the previous flag subcommand in a group of flags.
pub(crate) flag_subcmd_at: Option<usize>, flag_subcmd_at: Option<usize>,
/// Counter indicating the number of items to skip /// Counter indicating the number of items to skip
/// when revisiting the group of flags which includes the flag subcommand. /// when revisiting the group of flags which includes the flag subcommand.
pub(crate) flag_subcmd_skip: usize, flag_subcmd_skip: usize,
} }
// Initializing Methods // Initializing Methods
@ -48,6 +48,14 @@ impl<'help, 'app> Parser<'help, 'app> {
{ {
reqs.insert(a.id.clone()); 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 { Parser {
app, 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? // Should we color the help?
pub(crate) fn color_help(&self) -> ColorChoice { pub(crate) fn color_help(&self) -> ColorChoice {
#[cfg(feature = "color")] #[cfg(feature = "color")]
@ -96,7 +90,6 @@ impl<'help, 'app> Parser<'help, 'app> {
) -> ClapResult<()> { ) -> ClapResult<()> {
debug!("Parser::get_matches_with"); debug!("Parser::get_matches_with");
// Verify all positional assertions pass // Verify all positional assertions pass
self._build();
let mut subcmd_name: Option<String> = None; let mut subcmd_name: Option<String> = None;
let mut keep_state = false; let mut keep_state = false;
@ -264,7 +257,7 @@ impl<'help, 'app> Parser<'help, 'app> {
return Err(ClapError::no_equals( return Err(ClapError::no_equals(
self.app, self.app,
arg, arg,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
)); ));
} }
ParseResult::NoMatchingArg { arg } => { ParseResult::NoMatchingArg { arg } => {
@ -279,7 +272,7 @@ impl<'help, 'app> Parser<'help, 'app> {
self.app, self.app,
rest, rest,
arg, arg,
Usage::new(self).create_usage_no_title(&used), Usage::new(self.app, &self.required).create_usage_no_title(&used),
)) ))
} }
ParseResult::HelpFlag => { ParseResult::HelpFlag => {
@ -353,7 +346,7 @@ impl<'help, 'app> Parser<'help, 'app> {
return Err(ClapError::no_equals( return Err(ClapError::no_equals(
self.app, self.app,
arg, arg,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
)) ))
} }
ParseResult::NoMatchingArg { arg } => { ParseResult::NoMatchingArg { arg } => {
@ -361,7 +354,7 @@ impl<'help, 'app> Parser<'help, 'app> {
self.app, self.app,
arg, arg,
None, None,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
)); ));
} }
ParseResult::HelpFlag => { ParseResult::HelpFlag => {
@ -406,7 +399,7 @@ impl<'help, 'app> Parser<'help, 'app> {
self.app, self.app,
arg_os.to_str_lossy().into_owned(), arg_os.to_str_lossy().into_owned(),
None, None,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
)); ));
} }
@ -447,7 +440,7 @@ impl<'help, 'app> Parser<'help, 'app> {
None => { None => {
return Err(ClapError::invalid_utf8( return Err(ClapError::invalid_utf8(
self.app, self.app,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
)); ));
} }
}; };
@ -461,7 +454,7 @@ impl<'help, 'app> Parser<'help, 'app> {
if !allow_invalid_utf8 && v.to_str().is_none() { if !allow_invalid_utf8 && v.to_str().is_none() {
return Err(ClapError::invalid_utf8( return Err(ClapError::invalid_utf8(
self.app, self.app,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
)); ));
} }
sc_m.add_val_to( sc_m.add_val_to(
@ -506,7 +499,7 @@ impl<'help, 'app> Parser<'help, 'app> {
return Err(ClapError::missing_subcommand( return Err(ClapError::missing_subcommand(
self.app, self.app,
bn.to_string(), 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) { } else if self.is_set(AS::SubcommandRequiredElseHelp) {
debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true"); debug!("Parser::get_matches_with: SubcommandRequiredElseHelp=true");
@ -534,7 +527,7 @@ impl<'help, 'app> Parser<'help, 'app> {
return ClapError::unnecessary_double_dash( return ClapError::unnecessary_double_dash(
self.app, self.app,
arg_os.to_str_lossy().into_owned(), 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 +548,7 @@ impl<'help, 'app> Parser<'help, 'app> {
.as_ref() .as_ref()
.unwrap_or(&self.app.name) .unwrap_or(&self.app.name)
.to_string(), .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. // If the argument must be a subcommand.
@ -574,7 +567,7 @@ impl<'help, 'app> Parser<'help, 'app> {
self.app, self.app,
arg_os.to_str_lossy().into_owned(), arg_os.to_str_lossy().into_owned(),
None, None,
Usage::new(self).create_usage_with_title(&[]), Usage::new(self.app, &self.required).create_usage_with_title(&[]),
) )
} }
@ -721,7 +714,8 @@ impl<'help, 'app> Parser<'help, 'app> {
let mut mid_string = String::from(" "); let mut mid_string = String::from(" ");
if !self.is_set(AS::SubcommandsNegateReqs) { 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 { for s in &reqs {
mid_string.push_str(s); mid_string.push_str(s);
@ -1563,13 +1557,14 @@ impl<'help, 'app> Parser<'help, 'app> {
self.app, self.app,
format!("--{}", arg), format!("--{}", arg),
did_you_mean, did_you_mean,
Usage::new(self).create_usage_with_title(&*used), Usage::new(self.app, &self.required).create_usage_with_title(&*used),
) )
} }
pub(crate) fn write_help_err(&self) -> ClapResult<Colorizer> { pub(crate) fn write_help_err(&self) -> ClapResult<Colorizer> {
let usage = Usage::new(self.app, &self.required);
let mut c = Colorizer::new(true, self.color_help()); 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) Ok(c)
} }
@ -1580,9 +1575,10 @@ impl<'help, 'app> Parser<'help, 'app> {
); );
use_long = use_long && self.use_long_help(); 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()); 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(), Err(e) => e.into(),
_ => ClapError::for_app(self.app, c, ErrorKind::DisplayHelp, vec![]), _ => ClapError::for_app(self.app, c, ErrorKind::DisplayHelp, vec![]),
} }

View file

@ -50,7 +50,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
return Err(Error::empty_value( return Err(Error::empty_value(
self.p.app, self.p.app,
o, 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( return Err(Error::invalid_utf8(
self.p.app, 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() { if !arg.possible_vals.is_empty() {
@ -122,7 +122,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
.filter_map(PossibleValue::get_visible_name) .filter_map(PossibleValue::get_visible_name)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
arg, 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( return Err(Error::empty_value(
self.p.app, self.p.app,
arg, 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, self.p.app,
arg, arg,
Vec::new(), 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()) .chain(used_filtered.iter())
.cloned() .cloned()
.collect(); .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) { 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( return Err(Error::unexpected_multiple_usage(
self.p.app, self.p.app,
a, 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 { if let Some(max_occurs) = a.max_occurs {
@ -332,7 +332,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
a, a,
max_occurs, max_occurs,
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 { } else {
total_num 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) .expect(INVALID_UTF8)
.to_string(), .to_string(),
a.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, a,
num, num,
ma.num_vals(), 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 num == 0
@ -404,7 +404,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
return Err(Error::empty_value( return Err(Error::empty_value(
self.p.app, self.p.app,
a, a,
Usage::new(self.p).create_usage_with_title(&[]), Usage::new(self.p.app, &self.p.required).create_usage_with_title(&[]),
)); ));
} }
Ok(()) Ok(())
@ -514,7 +514,7 @@ impl<'help, 'app, 'parser> Validator<'help, 'app, 'parser> {
self.p.required 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); let req_args = usg.get_required_usage_from(&incl, Some(matcher), true);