diff --git a/Cargo.toml b/Cargo.toml index da02d8a255b8..dd44b388ffcf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,9 +22,9 @@ unicode-width = "0.1.4" unicode-segmentation = "1.0.1" strsim = { version = "0.6.0", optional = true } ansi_term = { version = "0.9.0", optional = true } -term_size = { version = "0.2.2", optional = true } +term_size = { version = "0.2.3", optional = true } yaml-rust = { version = "0.3.5", optional = true } -clippy = { version = "~0.0.112", optional = true } +clippy = { version = "~0.0.118", optional = true } atty = { version = "0.2.2", optional = true } [dev-dependencies] diff --git a/src/app/parser.rs b/src/app/parser.rs index ee3319627b2a..2eaeb83db3eb 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -215,10 +215,10 @@ impl<'a, 'b> Parser<'a, 'b> } // actually adds the arguments but from a borrow (which means we have to do some clonine) pub fn add_arg_ref(&mut self, a: &Arg<'a, 'b>) { - self.debug_asserts(&a); - self.add_conditional_reqs(&a); - self.add_arg_groups(&a); - self.add_reqs(&a); + self.debug_asserts(a); + self.add_conditional_reqs(a); + self.add_arg_groups(a); + self.add_reqs(a); if a.index.is_some() || (a.s.short.is_none() && a.s.long.is_none()) { let i = if a.index.is_none() { (self.positionals.len() + 1) @@ -777,7 +777,7 @@ impl<'a, 'b> Parser<'a, 'b> return (true, Some(v[0])); } } - return (false, None); + (false, None) } fn parse_help_subcommand(&self, it: &mut I) -> ClapResult<()> @@ -1322,7 +1322,7 @@ impl<'a, 'b> Parser<'a, 'b> .expect(INTERNAL_ERROR_MSG) .args { if self.groups.iter().any(|g| &g.name == &*n) { - args.extend(self.arg_names_in_group(&*n)); + args.extend(self.arg_names_in_group(n)); g_vec.push(*n); } else { args.push(*n); @@ -1502,6 +1502,7 @@ impl<'a, 'b> Parser<'a, 'b> self.did_you_mean_error(arg.to_str().expect(INVALID_UTF8), matcher).map(|_| None) } + #[cfg_attr(feature = "lints", allow(len_zero))] fn parse_short_arg(&mut self, matcher: &mut ArgMatcher<'a>, full_arg: &OsStr) @@ -1880,7 +1881,7 @@ impl<'a, 'b> Parser<'a, 'b> } // Only used for completion scripts due to bin_name messiness - #[cfg_attr(feature = "lints", allow(explicit_iter_loop))] + #[cfg_attr(feature = "lints", allow(block_in_if_condition_stmt))] pub fn find_subcommand(&'b self, sc: &str) -> Option<&'b App<'a, 'b>> { debugln!("Parser::find_subcommand: sc={}", sc); debugln!("Parser::find_subcommand: Currently in Parser...{}", diff --git a/src/app/usage.rs b/src/app/usage.rs index 3d79bf3851bb..72631cd9c1b9 100644 --- a/src/app/usage.rs +++ b/src/app/usage.rs @@ -1,4 +1,4 @@ -use args::{AnyArg, ArgMatcher}; +use args::{AnyArg, ArgMatcher, PosBuilder}; use args::settings::ArgSettings; use app::settings::AppSettings as AS; use app::parser::Parser; @@ -92,11 +92,8 @@ pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String { !p.has_visible_subcommands() { usage.push_str(" [--]") } - if p.has_positionals() && - p.positionals.values().any(|p| { - !p.is_set(ArgSettings::Required) && - !p.is_set(ArgSettings::Hidden) - }) { + let not_req_or_hidden= |p: &PosBuilder| !p.is_set(ArgSettings::Required) && !p.is_set(ArgSettings::Hidden); + if p.has_positionals() && p.positionals.values().any(not_req_or_hidden) { if let Some(args_tag) = p.get_args_tag() { usage.push_str(&*args_tag); } else { @@ -116,12 +113,10 @@ pub fn create_help_usage(p: &Parser, incl_reqs: bool) -> String { usage.push_str(&*name); usage.push_str(" "); } + } else if p.is_set(AS::SubcommandRequired) || p.is_set(AS::SubcommandRequiredElseHelp) { + usage.push_str(" "); } else { - if p.is_set(AS::SubcommandRequired) || p.is_set(AS::SubcommandRequiredElseHelp) { - usage.push_str(" "); - } else { - usage.push_str(" [SUBCOMMAND]"); - } + usage.push_str(" [SUBCOMMAND]"); } } usage.shrink_to_fit(); diff --git a/src/app/validator.rs b/src/app/validator.rs index 341b549e52c8..9130751a95a2 100644 --- a/src/app/validator.rs +++ b/src/app/validator.rs @@ -42,8 +42,8 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { if should_err { return Err(Error::empty_value(o, &*usage::create_error_usage(self.0, - matcher, - None), + matcher, + None), self.0.color())); } } @@ -81,9 +81,7 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { if self.0.is_set(AS::StrictUtf8) && val.to_str().is_none() { debugln!("Validator::validate_values: invalid UTF-8 found in val {:?}", val); - return Err(Error::invalid_utf8(&*usage::create_error_usage(self.0, - matcher, - None), + return Err(Error::invalid_utf8(&*usage::create_error_usage(self.0, matcher, None), self.0.color())); } if let Some(p_vals) = arg.possible_vals() { @@ -94,8 +92,8 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { p_vals, arg, &*usage::create_error_usage(self.0, - matcher, - None), + matcher, + None), self.0.color())); } } @@ -117,7 +115,7 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { } if let Some(vtor) = arg.validator_os() { debug!("Validator::validate_values: checking validator_os..."); - if let Err(e) = vtor(&val) { + if let Err(e) = vtor(val) { sdebugln!("error"); return Err(Error::value_validation(Some(arg), (*e).to_string_lossy().to_string(), @@ -236,8 +234,8 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { // Not the first time, and we don't allow multiples return Err(Error::unexpected_multiple_usage(a, &*usage::create_error_usage(self.0, - matcher, - None), + matcher, + None), self.0.color())); } Ok(()) @@ -276,8 +274,8 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { "ere" }, &*usage::create_error_usage(self.0, - matcher, - None), + matcher, + None), self.0.color())); } } @@ -292,7 +290,9 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { .to_str() .expect(INVALID_UTF8), a, - &*usage::create_error_usage(self.0, matcher, None), + &*usage::create_error_usage(self.0, + matcher, + None), self.0.color())); } } @@ -303,7 +303,9 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { return Err(Error::too_few_values(a, num, ma.vals.len(), - &*usage::create_error_usage(self.0, matcher, None), + &*usage::create_error_usage(self.0, + matcher, + None), self.0.color())); } } @@ -326,10 +328,9 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { debugln!("Validator::validate_arg_requires;"); if let Some(a_reqs) = a.requires() { for &(val, name) in a_reqs.iter().filter(|&&(val, _)| val.is_some()) { - if ma.vals.iter().any(|v| { - v == val.expect(INTERNAL_ERROR_MSG) && - !matcher.contains(name) - }) { + let missing_req = + |v| v == val.expect(INTERNAL_ERROR_MSG) && !matcher.contains(name); + if ma.vals.iter().any(missing_req) { return self.missing_required_error(matcher, None); } } @@ -364,10 +365,8 @@ impl<'a, 'b, 'z> Validator<'a, 'b, 'z> { // Validate the conditionally required args for &(a, v, r) in &self.0.r_ifs { if let Some(ma) = matcher.get(a) { - if matcher.get(r).is_none() { - if ma.vals.iter().any(|val| val == v) { - return self.missing_required_error(matcher, Some(r)); - } + if matcher.get(r).is_none() && ma.vals.iter().any(|val| val == v) { + return self.missing_required_error(matcher, Some(r)); } } } diff --git a/src/args/arg_matches.rs b/src/args/arg_matches.rs index 3a60c773ff16..aec7f4da7a24 100644 --- a/src/args/arg_matches.rs +++ b/src/args/arg_matches.rs @@ -110,7 +110,7 @@ impl<'a> ArgMatches<'a> { /// [`panic!`]: https://doc.rust-lang.org/std/macro.panic!.html pub fn value_of>(&self, name: S) -> Option<&str> { if let Some(arg) = self.args.get(name.as_ref()) { - if let Some(v) = arg.vals.iter().nth(0) { + if let Some(v) = arg.vals.get(0) { return Some(v.to_str().expect(INVALID_UTF8)); } } @@ -142,7 +142,7 @@ impl<'a> ArgMatches<'a> { /// [`Arg::values_of_lossy`]: ./struct.ArgMatches.html#method.values_of_lossy pub fn value_of_lossy>(&'a self, name: S) -> Option> { if let Some(arg) = self.args.get(name.as_ref()) { - if let Some(v) = arg.vals.iter().nth(0) { + if let Some(v) = arg.vals.get(0) { return Some(v.to_string_lossy()); } } @@ -179,7 +179,7 @@ impl<'a> ArgMatches<'a> { pub fn value_of_os>(&self, name: S) -> Option<&OsStr> { self.args .get(name.as_ref()) - .map_or(None, |arg| arg.vals.iter().nth(0).map(|v| v.as_os_str())) + .map_or(None, |arg| arg.vals.get(0).map(|v| v.as_os_str())) } /// Gets a [`Values`] struct which implements [`Iterator`] for values of a specific argument diff --git a/src/args/group.rs b/src/args/group.rs index d6cb9eb4018c..4ff2638a17d9 100644 --- a/src/args/group.rs +++ b/src/args/group.rs @@ -152,6 +152,7 @@ impl<'a> ArgGroup<'a> { /// assert!(m.is_present("flag")); /// ``` /// [argument]: ./struct.Arg.html + #[cfg_attr(feature = "lints", allow(should_assert_eq))] pub fn arg(mut self, n: &'a str) -> Self { assert!(self.name != n, "ArgGroup '{}' can not have same name as arg inside it", diff --git a/src/lib.rs b/src/lib.rs index c39f232e9e78..256c1420b529 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -527,6 +527,7 @@ #![cfg_attr(feature = "lints", deny(warnings))] #![cfg_attr(feature = "lints", allow(cyclomatic_complexity))] #![cfg_attr(feature = "lints", allow(doc_markdown))] +#![cfg_attr(feature = "lints", allow(explicit_iter_loop))] #[cfg(feature = "suggestions")] extern crate strsim; diff --git a/src/suggestions.rs b/src/suggestions.rs index 9a62be133d95..5c7cade5ed91 100644 --- a/src/suggestions.rs +++ b/src/suggestions.rs @@ -68,6 +68,7 @@ pub fn did_you_mean_suffix<'z, T, I>(arg: &str, } /// A helper to determine message formatting +#[derive(Copy, Clone, Debug)] pub enum DidYouMeanMessageStyle { /// Suggested value is a long flag LongFlag,