From 58512f2fcb430745f1ee6ee8f1c67f62dc216c73 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Mon, 29 Aug 2016 23:39:52 +0200 Subject: [PATCH 1/5] feat(Errors): Errors with custom description This is useful if a more meaningful message can be displayed to the user with `Error::exit`. For example, if a file is not found, the converted `io::Error` will give a message like: "error: entity not found" With this, it is possible to replace this message with a more useful one, like for instance: "error: configuration file not found" Coloring is respected. Some duplication in the `From::from` impls was reduced. --- src/errors.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/errors.rs b/src/errors.rs index 09ffb6f66fe..eded4856b96 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -788,6 +788,22 @@ impl Error { info: Some(vec![a]), } } + + /// Create an error with a custom description. + /// + /// This can be used in combination with `Error::exit` to exit your program + /// with a custom error message. + pub fn with_description(description: &str, kind: ErrorKind) -> Self { + let c = fmt::Colorizer { + use_stderr: true, + when: fmt::ColorWhen::Auto + }; + Error { + message: format!("{} {}", c.error("error:"), description), + kind: kind, + info: None, + } + } } impl StdError for Error { @@ -804,28 +820,12 @@ impl Display for Error { impl From for Error { fn from(e: io::Error) -> Self { - let c = fmt::Colorizer { - use_stderr: true, - when: fmt::ColorWhen::Auto - }; - Error { - message: format!("{} {}", c.error("error:"), e.description()), - kind: ErrorKind::Io, - info: None, - } + Error::with_description(e.description(), ErrorKind::Io) } } impl From for Error { fn from(e: std_fmt::Error) -> Self { - let c = fmt::Colorizer { - use_stderr: true, - when: fmt::ColorWhen::Auto - }; - Error { - message: format!("{} {}", c.error("error:"), e), - kind: ErrorKind::Format, - info: None, - } + Error::with_description(e.description(), ErrorKind::Format) } } From 24a6c61cf8151c3122472e79997619972932430e Mon Sep 17 00:00:00 2001 From: Kevin K Date: Mon, 5 Sep 2016 14:54:52 -0400 Subject: [PATCH 2/5] chore: updates term_size dep --- Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Cargo.toml b/Cargo.toml index fe1b083306e..1e81b0b3453 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -24,7 +24,7 @@ yaml-rust = { version = "~0.3.2", optional = true } clippy = { version = "~0.0.85", optional = true } unicode-width = "~0.1.3" unicode-segmentation = "~0.1.2" -term_size = { version = "~0.1.0", optional = true } +term_size = { version = "~0.2.0", optional = true } [dev-dependencies] regex = "~0.1.69" From 956965cc9403dd5e74165214ec08e53883926699 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Mon, 5 Sep 2016 15:14:47 -0400 Subject: [PATCH 3/5] chore: clippy run --- src/app/parser.rs | 73 ++++++++++++++++++---------------------------- src/completions.rs | 12 ++++++-- 2 files changed, 38 insertions(+), 47 deletions(-) diff --git a/src/app/parser.rs b/src/app/parser.rs index 67344f7065b..5ef4394351c 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -355,7 +355,7 @@ impl<'a, 'b> Parser<'a, 'b> if matcher.is_some() && matcher.as_ref().unwrap().contains(p) { continue; } - if let Some(p) = self.positionals.values().filter(|x| &x.name == &p).next() { + if let Some(p) = self.positionals.values().find(|x| &x.name == &p) { if args_in_groups.contains(&p.name) { continue; } @@ -590,7 +590,7 @@ impl<'a, 'b> Parser<'a, 'b> // Check to see if parsing a value from an option if let Some(nvo) = needs_val_of { // get the OptBuilder so we can check the settings - if let Some(opt) = self.opts.iter().filter(|o| &o.name == &nvo).next() { + if let Some(opt) = self.opts.iter().find(|o| &o.name == &nvo) { needs_val_of = try!(self.add_val_to_arg(opt, &arg_os, matcher)); // get the next value from the iterator continue; @@ -633,8 +633,7 @@ impl<'a, 'b> Parser<'a, 'b> } if let Some(c) = sc.subcommands .iter() - .filter(|s| &*s.p.meta.name == cmd) - .next() + .find(|s| &*s.p.meta.name == cmd) .map(|sc| &sc.p) { sc = c; if i == cmds.len() - 1 { @@ -642,7 +641,7 @@ impl<'a, 'b> Parser<'a, 'b> } } else if let Some(c) = sc.subcommands .iter() - .filter(|s| + .find(|s| if let Some(ref als) = s.p .meta .aliases { @@ -652,7 +651,6 @@ impl<'a, 'b> Parser<'a, 'b> false } ) - .next() .map(|sc| &sc.p) { sc = c; if i == cmds.len() - 1 { @@ -751,7 +749,7 @@ impl<'a, 'b> Parser<'a, 'b> let mut reqs_validated = false; if let Some(a) = needs_val_of { - if let Some(o) = self.opts.iter().filter(|o| &o.name == &a).next() { + if let Some(o) = self.opts.iter().find(|o| &o.name == &a) { try!(self.validate_required(matcher)); reqs_validated = true; let should_err = if let Some(v) = matcher.0.args.get(&*o.name) { @@ -765,8 +763,7 @@ impl<'a, 'b> Parser<'a, 'b> } else { return Err(Error::empty_value(self.positionals .values() - .filter(|p| &p.name == &a) - .next() + .find(|p| &p.name == &a) .expect(INTERNAL_ERROR_MSG), &*self.create_current_usage(matcher), self.color())); @@ -888,8 +885,7 @@ impl<'a, 'b> Parser<'a, 'b> mid_string.push_str(" "); if let Some(ref mut sc) = self.subcommands .iter_mut() - .filter(|s| &s.p.meta.name == &sc_name) - .next() { + .find(|s| &s.p.meta.name == &sc_name) { let mut sc_matcher = ArgMatcher::new(); // bin_name should be parent's bin_name + [] + the sc's name separated by // a space @@ -923,21 +919,21 @@ impl<'a, 'b> Parser<'a, 'b> fn blacklisted_from(&self, name: &str, matcher: &ArgMatcher) -> Option { for k in matcher.arg_names() { - if let Some(f) = self.flags.iter().filter(|f| &f.name == &k).next() { + if let Some(f) = self.flags.iter().find(|f| &f.name == &k) { if let Some(ref bl) = f.blacklist { if bl.contains(&name) { return Some(f.to_string()); } } } - if let Some(o) = self.opts.iter().filter(|o| &o.name == &k).next() { + if let Some(o) = self.opts.iter().find(|o| &o.name == &k) { if let Some(ref bl) = o.blacklist { if bl.contains(&name) { return Some(o.to_string()); } } } - if let Some(pos) = self.positionals.values().filter(|p| &p.name == &k).next() { + if let Some(pos) = self.positionals.values().find(|p| &p.name == &k) { if let Some(ref bl) = pos.blacklist { if bl.contains(&name) { return Some(pos.name.to_owned()); @@ -950,21 +946,21 @@ impl<'a, 'b> Parser<'a, 'b> fn overriden_from(&self, name: &str, matcher: &ArgMatcher) -> Option<&'a str> { for k in matcher.arg_names() { - if let Some(f) = self.flags.iter().filter(|f| &f.name == &k).next() { + if let Some(f) = self.flags.iter().find(|f| &f.name == &k) { if let Some(ref bl) = f.overrides { if bl.contains(&name.into()) { return Some(f.name); } } } - if let Some(o) = self.opts.iter().filter(|o| &o.name == &k).next() { + if let Some(o) = self.opts.iter().find(|o| &o.name == &k) { if let Some(ref bl) = o.overrides { if bl.contains(&name.into()) { return Some(o.name); } } } - if let Some(pos) = self.positionals.values().filter(|p| &p.name == &k).next() { + if let Some(pos) = self.positionals.values().find(|p| &p.name == &k) { if let Some(ref bl) = pos.overrides { if bl.contains(&name.into()) { return Some(pos.name); @@ -1004,16 +1000,15 @@ impl<'a, 'b> Parser<'a, 'b> let mut args = vec![]; for n in &self.groups.get(group).unwrap().args { - if let Some(f) = self.flags.iter().filter(|f| &f.name == n).next() { + if let Some(f) = self.flags.iter().find(|f| &f.name == n) { args.push(f.to_string()); - } else if let Some(f) = self.opts.iter().filter(|o| &o.name == n).next() { + } else if let Some(f) = self.opts.iter().find(|o| &o.name == n) { args.push(f.to_string()); } else if self.groups.contains_key(&**n) { g_vec.push(*n); } else if let Some(p) = self.positionals .values() - .filter(|p| &p.name == n) - .next() { + .find(|p| &p.name == n) { args.push(p.name.to_owned()); } } @@ -1101,13 +1096,11 @@ impl<'a, 'b> Parser<'a, 'b> .filter(|n| { if let Some(o) = self.opts .iter() - .filter(|&o| &&o.name == n) - .next() { + .find(|&o| &&o.name == n) { !o.settings.is_set(ArgSettings::Required) } else if let Some(p) = self.positionals .values() - .filter(|&p| &&p.name == n) - .next() { + .find(|&p| &&p.name == n) { !p.settings.is_set(ArgSettings::Required) } else { true // flags can't be required, so they're always true @@ -1195,8 +1188,7 @@ impl<'a, 'b> Parser<'a, 'b> if let Some(opt) = self.opts .iter() - .filter(|v| v.long.is_some() && &*v.long.unwrap() == arg) - .next() { + .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { debugln!("Found valid opt '{}'", opt.to_string()); let ret = try!(self.parse_opt(val, opt, matcher)); arg_post_processing!(self, opt, matcher); @@ -1204,8 +1196,7 @@ impl<'a, 'b> Parser<'a, 'b> return Ok(ret); } else if let Some(flag) = self.flags .iter() - .filter(|v| v.long.is_some() && &*v.long.unwrap() == arg) - .next() { + .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { debugln!("Found valid flag '{}'", flag.to_string()); // Only flags could be help or version, and we need to check the raw long // so this is the first point to check @@ -1241,8 +1232,7 @@ impl<'a, 'b> Parser<'a, 'b> // Value: val if let Some(opt) = self.opts .iter() - .filter(|&v| v.short.is_some() && v.short.unwrap() == c) - .next() { + .find(|&v| v.short.is_some() && v.short.unwrap() == c) { debugln!("Found valid short opt -{} in '{}'", c, arg); // Check for trailing concatenated value let p: Vec<_> = arg.splitn(2, c).collect(); @@ -1269,8 +1259,7 @@ impl<'a, 'b> Parser<'a, 'b> return Ok(ret); } else if let Some(flag) = self.flags .iter() - .filter(|&v| v.short.is_some() && v.short.unwrap() == c) - .next() { + .find(|&v| v.short.is_some() && v.short.unwrap() == c) { debugln!("Found valid short flag -{}", c); // Only flags can be help or version try!(self.check_for_help_and_version_char(c)); @@ -1484,13 +1473,11 @@ impl<'a, 'b> Parser<'a, 'b> continue; } else if let Some(opt) = self.opts .iter() - .filter(|o| &o.name == name) - .next() { + .find(|o| &o.name == name) { try!(self._validate_num_vals(opt, ma, matcher)); } else if let Some(pos) = self.positionals .values() - .filter(|p| &p.name == name) - .next() { + .find(|p| &p.name == name) { try!(self._validate_num_vals(pos, ma, matcher)); } } @@ -1575,15 +1562,15 @@ impl<'a, 'b> Parser<'a, 'b> if self.groups.values().any(|g| g.args.contains(name)) { continue 'outer; } - if let Some(a) = self.flags.iter().filter(|f| &f.name == name).next() { + if let Some(a) = self.flags.iter().find(|f| &f.name == name) { if self.is_missing_required_ok(a, matcher) { continue 'outer; } - } else if let Some(a) = self.opts.iter().filter(|o| &o.name == name).next() { + } else if let Some(a) = self.opts.iter().find(|o| &o.name == name) { if self.is_missing_required_ok(a, matcher) { continue 'outer; } - } else if let Some(a) = self.positionals.values().filter(|p| &p.name == name).next() { + } else if let Some(a) = self.positionals.values().find(|p| &p.name == name) { if self.is_missing_required_ok(a, matcher) { continue 'outer; } @@ -1651,15 +1638,13 @@ impl<'a, 'b> Parser<'a, 'b> if let Some(name) = suffix.1 { if let Some(opt) = self.opts .iter() - .filter(|o| o.long.is_some() && o.long.unwrap() == name) - .next() { + .find(|o| o.long.is_some() && o.long.unwrap() == name) { self.groups_for_arg(&*opt.name) .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps))); matcher.insert(&*opt.name); } else if let Some(flg) = self.flags .iter() - .filter(|f| f.long.is_some() && f.long.unwrap() == name) - .next() { + .find(|f| f.long.is_some() && f.long.unwrap() == name) { self.groups_for_arg(&*flg.name) .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps))); matcher.insert(&*flg.name); diff --git a/src/completions.rs b/src/completions.rs index c20ae535145..7da92937c94 100644 --- a/src/completions.rs +++ b/src/completions.rs @@ -140,12 +140,11 @@ complete -F _{name} {name} for sc in path.split('_').skip(1) { debugln!("iter;sc={}", sc); p = &p.subcommands.iter() - .filter(|s| s.p.meta.name == sc + .find(|s| s.p.meta.name == sc || (s.p.meta.aliases.is_some() && s.p.meta.aliases.as_ref() .unwrap() .iter() .any(|&(n,_)| n==sc ))) - .next() .unwrap().p; } let mut opts = p.short_list.iter().fold(String::new(), |acc, s| format!("{} -{}", acc, s)); @@ -167,7 +166,14 @@ complete -F _{name} {name} let mut p = self.p; for sc in path.split('_').skip(1) { debugln!("iter;sc={}", sc); - p = &p.subcommands.iter().filter(|s| s.p.meta.name == sc || (s.p.meta.aliases.is_some() && s.p.meta.aliases.as_ref().unwrap().iter().any(|&(n,_)| n==sc ))).next().unwrap().p; + p = &p.subcommands.iter() + .find(|s| s.p.meta.name == sc || + (s.p.meta.aliases.is_some() && + s.p.meta.aliases.as_ref() + .unwrap() + .iter() + .any(|&(n,_)| n==sc ))) + .unwrap().p; } let mut opts = String::new(); for o in &p.opts { From c6219ec5ed2dfc2119fc343ffffd9882127e867d Mon Sep 17 00:00:00 2001 From: Kevin K Date: Mon, 5 Sep 2016 15:16:17 -0400 Subject: [PATCH 4/5] chore: re-establish beta and udpate clippy nightly pin --- .travis.yml | 4 +--- Cargo.toml | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index c4ac6d01852..f5634c623ff 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,14 +2,12 @@ sudo: false language: rust rust: - nightly - - nightly-2016-07-20 + - nightly-2016-09-04 - beta - stable -# Only while clippy is failing matrix: allow_failures: - rust: nightly - - rust: beta before_script: - | pip install 'travis-cargo<0.2' --user && diff --git a/Cargo.toml b/Cargo.toml index 1e81b0b3453..5e4fd33cc32 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ libc = { version = "~0.2.9", optional = true } ansi_term = { version = "~0.8.0", optional = true } strsim = { version = "~0.5.1", optional = true } yaml-rust = { version = "~0.3.2", optional = true } -clippy = { version = "~0.0.85", optional = true } +clippy = { version = "~0.0.88", optional = true } unicode-width = "~0.1.3" unicode-segmentation = "~0.1.2" term_size = { version = "~0.2.0", optional = true } From 07e6e8ea3137960650e2729896fec011b5c99e8f Mon Sep 17 00:00:00 2001 From: Kevin K Date: Mon, 5 Sep 2016 15:29:40 -0400 Subject: [PATCH 5/5] style: rustfmt run --- src/app/help.rs | 112 ++++++---- src/app/macros.rs | 6 +- src/app/mod.rs | 52 +++-- src/app/parser.rs | 344 +++++++++++++++-------------- src/app/settings.rs | 5 +- src/args/any_arg.rs | 7 +- src/args/arg_builder/flag.rs | 18 +- src/args/arg_builder/option.rs | 15 +- src/args/arg_builder/positional.rs | 31 +-- src/args/arg_matcher.rs | 15 +- src/args/arg_matches.rs | 23 +- src/args/mod.rs | 11 +- src/args/settings.rs | 4 +- src/completions.rs | 176 +++++++++------ src/errors.rs | 102 ++++++--- src/fmt.rs | 36 +-- src/osstringext.rs | 6 +- src/usage_parser.rs | 8 +- 18 files changed, 561 insertions(+), 410 deletions(-) diff --git a/src/app/help.rs b/src/app/help.rs index 0c71bd427c2..652a3fa2c6c 100644 --- a/src/app/help.rs +++ b/src/app/help.rs @@ -1,21 +1,24 @@ -use std::io::{self, Cursor, Read, Write}; -use std::collections::BTreeMap; -use std::fmt::Display; -use std::cmp; -use std::usize; +// Std -use vec_map::VecMap; -use unicode_segmentation::UnicodeSegmentation; -use errors::{Error, Result as ClapResult}; +// Internal -use args::{AnyArg, ArgSettings, DispOrder}; use app::{App, AppSettings}; use app::parser::Parser; +use args::{AnyArg, ArgSettings, DispOrder}; +use errors::{Error, Result as ClapResult}; use fmt::{Format, Colorizer}; +use std::cmp; +use std::collections::BTreeMap; +use std::fmt::Display; +use std::io::{self, Cursor, Read, Write}; +use std::usize; #[cfg(feature = "wrap_help")] use term_size; +use unicode_segmentation::UnicodeSegmentation; + +use vec_map::VecMap; #[cfg(not(feature = "wrap_help"))] mod term_size { pub fn dimensions() -> Option<(usize, usize)> { @@ -90,19 +93,21 @@ pub struct Help<'a> { // Public Functions impl<'a> Help<'a> { /// Create a new `Help` instance. - pub fn new(w: &'a mut Write, next_line_help: bool, hide_pv: bool, color: bool, cizer: Colorizer, term_w: Option) -> Self { + pub fn new(w: &'a mut Write, + next_line_help: bool, + hide_pv: bool, + color: bool, + cizer: Colorizer, + term_w: Option) + -> Self { debugln!("fn=Help::new;"); Help { writer: w, next_line_help: next_line_help, hide_pv: hide_pv, term_w: match term_w { - Some(width) => if width == 0 { - usize::MAX - } else { - width - }, - None => term_size::dimensions().map_or(120, |(w, _)| w), + Some(width) => if width == 0 { usize::MAX } else { width }, + None => term_size::dimensions().map_or(120, |(w, _)| w), }, color: color, cizer: cizer, @@ -312,7 +317,8 @@ impl<'a> Help<'a> { let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp); let width = self.term_w; let taken = (longest + 12) + str_width(&*spec_vals); - let force_next_line = !nlh && width >= taken && str_width(h) > (width - taken) && (taken as f32 / width as f32) > 0.25; + let force_next_line = !nlh && width >= taken && str_width(h) > (width - taken) && + (taken as f32 / width as f32) > 0.25; if arg.has_switch() { if !(nlh || force_next_line) { @@ -400,9 +406,13 @@ impl<'a> Help<'a> { // We calculate with longest+12 since if it's already NLH we don't care let taken = (longest + 12) + str_width(&*spec_vals); - let force_next_line = !nlh && width >= taken && str_width(h) > (width - taken) && (taken as f32 / width as f32) > 0.25; + let force_next_line = !nlh && width >= taken && str_width(h) > (width - taken) && + (taken as f32 / width as f32) > 0.25; debugln!("Force Next Line...{:?}", force_next_line); - debugln!("Force Next Line math (help_len > (width - flags/opts/spcs))...{} > ({} - {})", str_width(h), width, taken); + debugln!("Force Next Line math (help_len > (width - flags/opts/spcs))...{} > ({} - {})", + str_width(h), + width, + taken); let spcs = if nlh || force_next_line { 8 // "tab" + "tab" @@ -488,9 +498,9 @@ impl<'a> Help<'a> { if self.color { format!(" [values: {}]", pv.iter() - .map(|v| format!("{}", self.cizer.good(v))) - .collect::>() - .join(", ")) + .map(|v| format!("{}", self.cizer.good(v))) + .collect::>() + .join(", ")) } else { format!(" [values: {}]", pv.join(", ")) } @@ -501,14 +511,14 @@ impl<'a> Help<'a> { } else if let Some(ref aliases) = a.aliases() { debugln!("Writing aliases"); return format!(" [aliases: {}]", - if self.color { - aliases.iter() - .map(|v| format!("{}", self.cizer.good(v))) - .collect::>() - .join(", ") - } else { - aliases.join(", ") - }); + if self.color { + aliases.iter() + .map(|v| format!("{}", self.cizer.good(v))) + .collect::>() + .join(", ") + } else { + aliases.join(", ") + }); } else if !self.hide_pv { debugln!("Writing values"); if let Some(pv) = a.possible_vals() { @@ -516,9 +526,9 @@ impl<'a> Help<'a> { return if self.color { format!(" [values: {}]", pv.iter() - .map(|v| format!("{}", self.cizer.good(v))) - .collect::>() - .join(", ")) + .map(|v| format!("{}", self.cizer.good(v))) + .collect::>() + .join(", ")) } else { format!(" [values: {}]", pv.join(", ")) }; @@ -547,8 +557,8 @@ impl<'a> Help<'a> { if unified_help && (flags || opts) { let opts_flags = parser.iter_flags() - .map(as_arg_trait) - .chain(parser.iter_opts().map(as_arg_trait)); + .map(as_arg_trait) + .chain(parser.iter_opts().map(as_arg_trait)); try!(color!(self, "OPTIONS:\n", warning)); try!(self.write_args(opts_flags)); first = false; @@ -556,7 +566,7 @@ impl<'a> Help<'a> { if flags { try!(color!(self, "FLAGS:\n", warning)); try!(self.write_args(parser.iter_flags() - .map(as_arg_trait))); + .map(as_arg_trait))); first = false; } if opts { @@ -826,11 +836,11 @@ impl<'a> Help<'a> { _ => continue, }; - debugln!("iter;tag_buf={};", unsafe { - String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length] - .iter() - .map(|&i|i) - .collect::>()) + debugln!("iter;tag_buf={};", unsafe { + String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length] + .iter() + .map(|&i| i) + .collect::>()) }); match &tag_buf.get_ref()[0..tag_length] { b"?" => { @@ -862,21 +872,21 @@ impl<'a> Help<'a> { } b"unified" => { let opts_flags = parser.iter_flags() - .map(as_arg_trait) - .chain(parser.iter_opts().map(as_arg_trait)); + .map(as_arg_trait) + .chain(parser.iter_opts().map(as_arg_trait)); try!(self.write_args(opts_flags)); } b"flags" => { try!(self.write_args(parser.iter_flags() - .map(as_arg_trait))); + .map(as_arg_trait))); } b"options" => { try!(self.write_args(parser.iter_opts() - .map(as_arg_trait))); + .map(as_arg_trait))); } b"positionals" => { try!(self.write_args(parser.iter_positionals() - .map(as_arg_trait))); + .map(as_arg_trait))); } b"subcommands" => { try!(self.write_subcommands(&parser)); @@ -904,7 +914,9 @@ impl<'a> Help<'a> { #[cfg_attr(feature = "lints", allow(explicit_counter_loop))] fn wrap_help(help: &mut String, longest_w: usize, avail_chars: usize) { - debugln!("fn=wrap_help;longest_w={},avail_chars={}", longest_w, avail_chars); + debugln!("fn=wrap_help;longest_w={},avail_chars={}", + longest_w, + avail_chars); debug!("Enough space to wrap..."); if longest_w < avail_chars { sdebugln!("Yes"); @@ -913,9 +925,11 @@ fn wrap_help(help: &mut String, longest_w: usize, avail_chars: usize) { let mut i = 0; for (idx, g) in (&*help.clone()).grapheme_indices(true) { debugln!("iter;idx={},g={}", idx, g); - if g != " " { continue; } + if g != " " { + continue; + } if str_width(&help[j..idx + (2 * i)]) < avail_chars { - debugln!("Still enough space..."); + debugln!("Still enough space..."); prev_space = idx; continue; } diff --git a/src/app/macros.rs b/src/app/macros.rs index 022b05fcb65..59f7a4dfc64 100644 --- a/src/app/macros.rs +++ b/src/app/macros.rs @@ -104,8 +104,10 @@ macro_rules! validate_multiples { ($_self:ident, $a:ident, $m:ident) => { debugln!("macro=validate_multiples!;"); if $m.contains(&$a.name) && !$a.settings.is_set(ArgSettings::Multiple) { - // Not the first time, and we don't allow multiples - return Err(Error::unexpected_multiple_usage($a, &*$_self.create_current_usage($m), $_self.color())) +// Not the first time, and we don't allow multiples + return Err(Error::unexpected_multiple_usage($a, + &*$_self.create_current_usage($m), + $_self.color())) } }; } diff --git a/src/app/mod.rs b/src/app/mod.rs index 3c7553444e8..6809cef97ec 100644 --- a/src/app/mod.rs +++ b/src/app/mod.rs @@ -6,28 +6,31 @@ pub mod parser; mod meta; mod help; -pub use self::settings::AppSettings; +// Std + +// Internal +use app::help::Help; +use app::parser::Parser; +use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings}; +use errors::Error; +use errors::Result as ClapResult; +pub use self::settings::AppSettings; +use shell::Shell; +use std::borrow::Borrow; use std::env; +use std::ffi::OsString; +use std::fmt; use std::io::{self, BufRead, BufWriter, Write}; use std::path::Path; use std::process; -use std::ffi::OsString; -use std::borrow::Borrow; -use std::result::Result as StdResult; use std::rc::Rc; -use std::fmt; +use std::result::Result as StdResult; +// Third Party +use vec_map::VecMap; #[cfg(feature = "yaml")] use yaml_rust::Yaml; -use vec_map::VecMap; - -use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings}; -use app::parser::Parser; -use app::help::Help; -use errors::Error; -use errors::Result as ClapResult; -use shell::Shell; /// Used to create a representation of a command line program and all possible command line /// arguments. Application settings are set using the "builder pattern" with the @@ -1086,7 +1089,10 @@ impl<'a, 'b> App<'a, 'b> { /// `/target/debug/build/myapp-/out/myapp.bash-completion`. /// /// Fish shell completions will use the file format `{bin_name}.fish` - pub fn gen_completions, S: Into>(&mut self, bin_name: S, for_shell: Shell, out_dir: T) { + pub fn gen_completions, S: Into>(&mut self, + bin_name: S, + for_shell: Shell, + out_dir: T) { self.p.meta.bin_name = Some(bin_name.into()); self.p.gen_completions(for_shell, out_dir.into()); } @@ -1124,7 +1130,10 @@ impl<'a, 'b> App<'a, 'b> { /// ```shell /// $ myapp generate-bash-completions > /etc/bash_completion.d/myapp /// ``` - pub fn gen_completions_to>(&mut self, bin_name: S, for_shell: Shell, buf: &mut W) { + pub fn gen_completions_to>(&mut self, + bin_name: S, + for_shell: Shell, + buf: &mut W) { self.p.meta.bin_name = Some(bin_name.into()); self.p.gen_completions_to(for_shell, buf); } @@ -1342,11 +1351,7 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> { is_sc = Some(yaml_hash.get(sc_key).unwrap()); App::new(sc_key.as_str().unwrap()) }; - yaml = if let Some(sc) = is_sc { - sc - } else { - yaml - }; + yaml = if let Some(sc) = is_sc { sc } else { yaml }; macro_rules! yaml_str { ($a:ident, $y:ident, $i:ident) => { @@ -1402,7 +1407,9 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> { if let Some(v) = yaml["global_settings"].as_vec() { for ys in v { if let Some(s) = ys.as_str() { - a = a.global_setting(s.parse().ok().expect("unknown AppSetting found in YAML file")); + a = a.global_setting(s.parse() + .ok() + .expect("unknown AppSetting found in YAML file")); } } } else { @@ -1531,7 +1538,8 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> { } fn aliases(&self) -> Option> { if let Some(ref aliases) = self.p.meta.aliases { - let vis_aliases: Vec<_> = aliases.iter().filter_map(|&(n,v)| if v { Some(n) } else {None}).collect(); + let vis_aliases: Vec<_> = + aliases.iter().filter_map(|&(n, v)| if v { Some(n) } else { None }).collect(); if vis_aliases.is_empty() { None } else { diff --git a/src/app/parser.rs b/src/app/parser.rs index 5ef4394351c..1370840d37a 100644 --- a/src/app/parser.rs +++ b/src/app/parser.rs @@ -1,33 +1,38 @@ -use std::collections::{BTreeMap, HashMap, VecDeque}; -use std::slice::Iter; -use std::io::{self, BufWriter, Write}; -use std::ffi::{OsStr, OsString}; -use std::fmt::Display; -#[cfg(feature = "debug")] -use std::os::unix::ffi::OsStrExt; +// Std -use vec_map::{self, VecMap}; -use app::help::Help; +// Internal + +use INTERNAL_ERROR_MSG; +use INVALID_UTF8; +use SubCommand; use app::App; -use args::{Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder}; +use app::help::Help; +use app::meta::AppMeta; use app::settings::{AppFlags, AppSettings}; use args::{AnyArg, ArgMatcher}; +use args::{Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder}; +use args::MatchedArg; use args::settings::ArgSettings; +use completions::ComplGen; use errors::{Error, ErrorKind}; use errors::Result as ClapResult; -use INVALID_UTF8; -use suggestions; -use INTERNAL_ERROR_MSG; -use SubCommand; use fmt::{Format, ColorWhen}; use osstringext::OsStrExt2; -use app::meta::AppMeta; -use args::MatchedArg; use shell::Shell; -use completions::ComplGen; +use std::collections::{BTreeMap, HashMap, VecDeque}; +use std::ffi::{OsStr, OsString}; +use std::fmt::Display; use std::fs::File; +use std::io::{self, BufWriter, Write}; +#[cfg(feature = "debug")] +use std::os::unix::ffi::OsStrExt; use std::path::PathBuf; +use std::slice::Iter; +use suggestions; + +// Third Party +use vec_map::{self, VecMap}; #[allow(missing_debug_implementations)] #[doc(hidden)] @@ -91,14 +96,14 @@ impl<'a, 'b> Parser<'a, 'b> pub fn help_short(&mut self, s: &str) { self.help_short = s.trim_left_matches(|c| c == '-') - .chars() - .nth(0); + .chars() + .nth(0); } pub fn version_short(&mut self, s: &str) { self.version_short = s.trim_left_matches(|c| c == '-') - .chars() - .nth(0); + .chars() + .nth(0); } pub fn gen_completions_to(&mut self, for_shell: Shell, buf: &mut W) { @@ -134,8 +139,8 @@ impl<'a, 'b> Parser<'a, 'b> format!("Non-unique argument name: {} is already in use", a.name)); if let Some(ref grps) = a.group { for g in grps { - let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g)); - ag.args.push(a.name); + let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g)); + ag.args.push(a.name); } } if let Some(s) = a.short { @@ -248,7 +253,7 @@ impl<'a, 'b> Parser<'a, 'b> self.meta.version.is_some() { sdebugln!("Yes"); subcmd = subcmd.setting(AppSettings::GlobalVersion) - .version(self.meta.version.unwrap()); + .version(self.meta.version.unwrap()); } else { sdebugln!("No"); } @@ -365,7 +370,7 @@ impl<'a, 'b> Parser<'a, 'b> debugln!("args_in_groups={:?}", args_in_groups); for (_, s) in pmap { if (!args_in_groups.is_empty()) && (args_in_groups.contains(&&*s)) { - continue; + continue; } ret_val.push_back(s); @@ -385,7 +390,7 @@ impl<'a, 'b> Parser<'a, 'b> let mut g_vec = vec![]; for g in grps.into_iter() { let g_string = self.args_in_group(g) - .join("|"); + .join("|"); g_vec.push(format!("<{}>", &g_string[..g_string.len()])); } g_vec.dedup(); @@ -413,10 +418,10 @@ impl<'a, 'b> Parser<'a, 'b> } } debugln!("Arg not required..."); - count +=1; + count += 1; } else { debugln!("Arg not required..."); - count +=1; + count += 1; } } if count > 1 || self.positionals.len() > 1 { @@ -578,14 +583,18 @@ impl<'a, 'b> Parser<'a, 'b> if !self.trailing_vals { // Does the arg match a subcommand name, or any of it's aliases (if defined) let pos_sc = self.subcommands - .iter() - .any(|s| &s.p.meta.name[..] == &*arg_os || - (s.p.meta.aliases.is_some() && - s.p.meta.aliases - .as_ref() - .unwrap() - .iter() - .any(|&(a, _)| a == &*arg_os))); + .iter() + .any(|s| { + &s.p.meta.name[..] == &*arg_os || + (s.p.meta.aliases.is_some() && + s.p + .meta + .aliases + .as_ref() + .unwrap() + .iter() + .any(|&(a, _)| a == &*arg_os)) + }); if (!starts_new_arg || self.is_set(AppSettings::AllowLeadingHyphen)) && !pos_sc { // Check to see if parsing a value from an option if let Some(nvo) = needs_val_of { @@ -622,36 +631,36 @@ impl<'a, 'b> Parser<'a, 'b> let cmds: Vec = it.map(|c| c.into()).collect(); let mut help_help = false; let mut bin_name = self.meta - .bin_name - .as_ref() - .unwrap_or(&self.meta.name).clone(); + .bin_name + .as_ref() + .unwrap_or(&self.meta.name) + .clone(); let mut sc = { let mut sc: &Parser = self; for (i, cmd) in cmds.iter().enumerate() { - if &*cmd.to_string_lossy() == "help" { // cmd help help + if &*cmd.to_string_lossy() == "help" { + // cmd help help help_help = true; } if let Some(c) = sc.subcommands - .iter() - .find(|s| &*s.p.meta.name == cmd) - .map(|sc| &sc.p) { + .iter() + .find(|s| &*s.p.meta.name == cmd) + .map(|sc| &sc.p) { sc = c; if i == cmds.len() - 1 { break; } } else if let Some(c) = sc.subcommands - .iter() - .find(|s| - if let Some(ref als) = s.p - .meta - .aliases { - als.iter() - .any(|&(a, _)| &a == &&*cmd.to_string_lossy()) - } else { - false - } - ) - .map(|sc| &sc.p) { + .iter() + .find(|s| if let Some(ref als) = s.p + .meta + .aliases { + als.iter() + .any(|&(a, _)| &a == &&*cmd.to_string_lossy()) + } else { + false + }) + .map(|sc| &sc.p) { sc = c; if i == cmds.len() - 1 { break; @@ -691,9 +700,11 @@ impl<'a, 'b> Parser<'a, 'b> subcmd_name = Some(arg_os.to_str().expect(INVALID_UTF8).to_owned()); break; } else if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(), - self.subcommands - .iter() - .map(|s| &s.p.meta.name)) { + self.subcommands + .iter() + .map(|s| { + &s.p.meta.name + })) { return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(), cdate, self.meta @@ -713,9 +724,8 @@ impl<'a, 'b> Parser<'a, 'b> Some(s) => s.to_string(), None => { if !self.settings.is_set(AppSettings::StrictUtf8) { - return Err( - Error::invalid_utf8(&*self.create_current_usage(matcher), self.color()) - ); + return Err(Error::invalid_utf8(&*self.create_current_usage(matcher), + self.color())); } arg_os.to_string_lossy().into_owned() } @@ -727,9 +737,8 @@ impl<'a, 'b> Parser<'a, 'b> let a = v.into(); if let None = a.to_str() { if !self.settings.is_set(AppSettings::StrictUtf8) { - return Err( - Error::invalid_utf8(&*self.create_current_usage(matcher), self.color()) - ); + return Err(Error::invalid_utf8(&*self.create_current_usage(matcher), + self.color())); } } sc_m.add_val_to("", &a); @@ -758,7 +767,9 @@ impl<'a, 'b> Parser<'a, 'b> true }; if should_err { - return Err(Error::empty_value(o, &*self.create_current_usage(matcher), self.color())); + return Err(Error::empty_value(o, + &*self.create_current_usage(matcher), + self.color())); } } else { return Err(Error::empty_value(self.positionals @@ -787,22 +798,26 @@ impl<'a, 'b> Parser<'a, 'b> self.subcommands .iter() .filter(|sc| sc.p.meta.aliases.is_some()) - .filter_map(|sc| if sc.p.meta.aliases - .as_ref() - .unwrap() - .iter() - .any(|&(a, _)| &a == &&*pos_sc_name) { - Some(sc.p.meta.name.clone()) - } else { - None - }) + .filter_map(|sc| if sc.p + .meta + .aliases + .as_ref() + .unwrap() + .iter() + .any(|&(a, _)| &a == &&*pos_sc_name) { + Some(sc.p.meta.name.clone()) + } else { + None + }) .next() .expect(INTERNAL_ERROR_MSG) }; try!(self.parse_subcommand(sc_name, matcher, it)); } else if self.is_set(AppSettings::SubcommandRequired) { let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name); - return Err(Error::missing_subcommand(bn, &self.create_current_usage(matcher), self.color())); + return Err(Error::missing_subcommand(bn, + &self.create_current_usage(matcher), + self.color())); } else if self.is_set(AppSettings::SubcommandRequiredElseHelp) { let mut out = vec![]; try!(self.write_help_err(&mut out)); @@ -884,8 +899,8 @@ impl<'a, 'b> Parser<'a, 'b> } mid_string.push_str(" "); if let Some(ref mut sc) = self.subcommands - .iter_mut() - .find(|s| &s.p.meta.name == &sc_name) { + .iter_mut() + .find(|s| &s.p.meta.name == &sc_name) { let mut sc_matcher = ArgMatcher::new(); // bin_name should be parent's bin_name + [] + the sc's name separated by // a space @@ -1007,8 +1022,8 @@ impl<'a, 'b> Parser<'a, 'b> } else if self.groups.contains_key(&**n) { g_vec.push(*n); } else if let Some(p) = self.positionals - .values() - .find(|p| &p.name == n) { + .values() + .find(|p| &p.name == n) { args.push(p.name.to_owned()); } } @@ -1061,7 +1076,7 @@ impl<'a, 'b> Parser<'a, 'b> self.flags.push(arg); } if !self.settings.is_set(AppSettings::DisableVersion) && - self.is_set(AppSettings::NeedsLongVersion) { + self.is_set(AppSettings::NeedsLongVersion) { debugln!("Building --version"); if self.version_short.is_none() && !self.short_list.contains(&'V') { self.version_short = Some('V'); @@ -1084,7 +1099,7 @@ impl<'a, 'b> Parser<'a, 'b> debugln!("Building help"); self.subcommands .push(App::new("help") - .about("Prints this message or the help of the given subcommand(s)")); + .about("Prints this message or the help of the given subcommand(s)")); } } @@ -1092,22 +1107,22 @@ impl<'a, 'b> Parser<'a, 'b> // because those will be listed in self.required pub fn create_current_usage(&self, matcher: &'b ArgMatcher<'a>) -> String { self.create_usage(&*matcher.arg_names() - .iter() - .filter(|n| { - if let Some(o) = self.opts - .iter() - .find(|&o| &&o.name == n) { - !o.settings.is_set(ArgSettings::Required) - } else if let Some(p) = self.positionals - .values() - .find(|&p| &&p.name == n) { - !p.settings.is_set(ArgSettings::Required) - } else { - true // flags can't be required, so they're always true - } - }) - .map(|&n| n) - .collect::>()) + .iter() + .filter(|n| { + if let Some(o) = self.opts + .iter() + .find(|&o| &&o.name == n) { + !o.settings.is_set(ArgSettings::Required) + } else if let Some(p) = self.positionals + .values() + .find(|&p| &&p.name == n) { + !p.settings.is_set(ArgSettings::Required) + } else { + true // flags can't be required, so they're always true + } + }) + .map(|&n| n) + .collect::>()) } fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> { @@ -1187,16 +1202,16 @@ impl<'a, 'b> Parser<'a, 'b> }; if let Some(opt) = self.opts - .iter() - .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { + .iter() + .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { debugln!("Found valid opt '{}'", opt.to_string()); let ret = try!(self.parse_opt(val, opt, matcher)); arg_post_processing!(self, opt, matcher); return Ok(ret); } else if let Some(flag) = self.flags - .iter() - .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { + .iter() + .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { debugln!("Found valid flag '{}'", flag.to_string()); // Only flags could be help or version, and we need to check the raw long // so this is the first point to check @@ -1231,8 +1246,8 @@ impl<'a, 'b> Parser<'a, 'b> // Option: -o // Value: val if let Some(opt) = self.opts - .iter() - .find(|&v| v.short.is_some() && v.short.unwrap() == c) { + .iter() + .find(|&v| v.short.is_some() && v.short.unwrap() == c) { debugln!("Found valid short opt -{} in '{}'", c, arg); // Check for trailing concatenated value let p: Vec<_> = arg.splitn(2, c).collect(); @@ -1258,8 +1273,8 @@ impl<'a, 'b> Parser<'a, 'b> return Ok(ret); } else if let Some(flag) = self.flags - .iter() - .find(|&v| v.short.is_some() && v.short.unwrap() == c) { + .iter() + .find(|&v| v.short.is_some() && v.short.unwrap() == c) { debugln!("Found valid short flag -{}", c); // Only flags can be help or version try!(self.check_for_help_and_version_char(c)); @@ -1295,7 +1310,9 @@ impl<'a, 'b> Parser<'a, 'b> let v = fv.trim_left_matches(b'='); if !opt.is_set(ArgSettings::EmptyValues) && v.len_() == 0 { sdebugln!("Found Empty - Error"); - return Err(Error::empty_value(opt, &*self.create_current_usage(matcher), self.color())); + return Err(Error::empty_value(opt, + &*self.create_current_usage(matcher), + self.color())); } sdebugln!("Found - {:?}, len: {}", v, v.len_()); debugln!("{:?} contains '='...{:?}", fv, fv.starts_with(&[b'='])); @@ -1308,7 +1325,8 @@ impl<'a, 'b> Parser<'a, 'b> // Increment or create the group "args" self.groups_for_arg(opt.name).and_then(|vec| Some(matcher.inc_occurrences_of(&*vec))); - if val.is_none() || !has_eq && (opt.is_set(ArgSettings::Multiple) && matcher.needs_more_vals(opt)) { + if val.is_none() || + !has_eq && (opt.is_set(ArgSettings::Multiple) && matcher.needs_more_vals(opt)) { return Ok(Some(opt.name)); } Ok(None) @@ -1332,7 +1350,8 @@ impl<'a, 'b> Parser<'a, 'b> ret = try!(self.add_single_val_to_arg(arg, v, matcher)); } // If there was a delimiter used, we're not looking for more values - if val.contains_byte(delim as u32 as u8) || arg.is_set(ArgSettings::RequireDelimiter) { + if val.contains_byte(delim as u32 as u8) || + arg.is_set(ArgSettings::RequireDelimiter) { ret = None; } } @@ -1472,12 +1491,12 @@ impl<'a, 'b> Parser<'a, 'b> if self.groups.contains_key(&**name) { continue; } else if let Some(opt) = self.opts - .iter() - .find(|o| &o.name == name) { + .iter() + .find(|o| &o.name == name) { try!(self._validate_num_vals(opt, ma, matcher)); } else if let Some(pos) = self.positionals - .values() - .find(|p| &p.name == name) { + .values() + .find(|p| &p.name == name) { try!(self._validate_num_vals(pos, ma, matcher)); } } @@ -1521,13 +1540,13 @@ impl<'a, 'b> Parser<'a, 'b> if (ma.vals.len() as u64) > num { debugln!("Sending error TooManyValues"); return Err(Error::too_many_values(ma.vals - .get(ma.vals - .keys() - .last() - .expect(INTERNAL_ERROR_MSG)) - .expect(INTERNAL_ERROR_MSG) - .to_str() - .expect(INVALID_UTF8), + .get(ma.vals + .keys() + .last() + .expect(INTERNAL_ERROR_MSG)) + .expect(INTERNAL_ERROR_MSG) + .to_str() + .expect(INVALID_UTF8), a, &*self.create_current_usage(matcher), self.color())); @@ -1575,21 +1594,21 @@ impl<'a, 'b> Parser<'a, 'b> continue 'outer; } } - let err = if self.settings.is_set(AppSettings::ArgRequiredElseHelp) && - matcher.is_empty() { - self._help().unwrap_err() - } else { - let mut reqs = self.required.iter().map(|&r| &*r).collect::>(); - reqs.retain(|n| !matcher.contains(n)); - reqs.dedup(); - Error::missing_required_argument( + let err = + if self.settings.is_set(AppSettings::ArgRequiredElseHelp) && matcher.is_empty() { + self._help().unwrap_err() + } else { + let mut reqs = self.required.iter().map(|&r| &*r).collect::>(); + reqs.retain(|n| !matcher.contains(n)); + reqs.dedup(); + Error::missing_required_argument( &*self.get_required_from(&*reqs, Some(matcher)) .iter() .fold(String::new(), |acc, s| acc + &format!("\n {}", Format::Error(s))[..]), &*self.create_current_usage(matcher), self.color()) - }; + }; return Err(err); } Ok(()) @@ -1602,8 +1621,8 @@ impl<'a, 'b> Parser<'a, 'b> for n in bl.iter() { if matcher.contains(n) || self.groups - .get(n) - .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) { + .get(n) + .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) { return true; } } @@ -1612,15 +1631,15 @@ impl<'a, 'b> Parser<'a, 'b> for n in ru.iter() { if matcher.contains(n) || self.groups - .get(n) - .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) { - if !a.is_set(ArgSettings::RequiredUnlessAll) { - return true; - } - found_any = true; - } else if a.is_set(ArgSettings::RequiredUnlessAll) { - return false; - } + .get(n) + .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) { + if !a.is_set(ArgSettings::RequiredUnlessAll) { + return true; + } + found_any = true; + } else if a.is_set(ArgSettings::RequiredUnlessAll) { + return false; + } } return found_any; } @@ -1637,14 +1656,14 @@ impl<'a, 'b> Parser<'a, 'b> // Add the arg to the matches to build a proper usage string if let Some(name) = suffix.1 { if let Some(opt) = self.opts - .iter() - .find(|o| o.long.is_some() && o.long.unwrap() == name) { + .iter() + .find(|o| o.long.is_some() && o.long.unwrap() == name) { self.groups_for_arg(&*opt.name) .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps))); matcher.insert(&*opt.name); } else if let Some(flg) = self.flags - .iter() - .find(|f| f.long.is_some() && f.long.unwrap() == name) { + .iter() + .find(|f| f.long.is_some() && f.long.unwrap() == name) { self.groups_for_arg(&*flg.name) .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps))); matcher.insert(&*flg.name); @@ -1652,7 +1671,10 @@ impl<'a, 'b> Parser<'a, 'b> } let used_arg = format!("--{}", arg); - Err(Error::unknown_argument(&*used_arg, &*suffix.0, &*self.create_current_usage(matcher), self.color())) + Err(Error::unknown_argument(&*used_arg, + &*suffix.0, + &*self.create_current_usage(matcher), + self.color())) } // Creates a usage string if one was not provided by the user manually. This happens just @@ -1677,17 +1699,17 @@ impl<'a, 'b> Parser<'a, 'b> usage.push_str(&*u); } else if used.is_empty() { usage.push_str(&*self.meta - .usage - .as_ref() - .unwrap_or(self.meta - .bin_name - .as_ref() - .unwrap_or(&self.meta.name))); + .usage + .as_ref() + .unwrap_or(self.meta + .bin_name + .as_ref() + .unwrap_or(&self.meta.name))); let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect(); reqs.dedup(); let req_string = self.get_required_from(&reqs, None) - .iter() - .fold(String::new(), |a, s| a + &format!(" {}", s)[..]); + .iter() + .fold(String::new(), |a, s| a + &format!(" {}", s)[..]); let flags = self.needs_flags_tag(); if flags && !self.is_set(AppSettings::UnifiedHelpMessage) { @@ -1741,17 +1763,17 @@ impl<'a, 'b> Parser<'a, 'b> hs.extend_from_slice(used); let r_string = self.get_required_from(&hs, None) - .iter() - .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]); + .iter() + .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]); usage.push_str(&self.meta - .usage - .as_ref() - .unwrap_or(self.meta - .bin_name - .as_ref() - .unwrap_or(&self.meta - .name))[..]); + .usage + .as_ref() + .unwrap_or(self.meta + .bin_name + .as_ref() + .unwrap_or(&self.meta + .name))[..]); usage.push_str(&*r_string); if self.is_set(AppSettings::SubcommandRequired) { usage.push_str(" "); diff --git a/src/app/settings.rs b/src/app/settings.rs index 15005d6d482..ed0000f1b39 100644 --- a/src/app/settings.rs +++ b/src/app/settings.rs @@ -1,5 +1,6 @@ -use std::str::FromStr; + use std::ascii::AsciiExt; +use std::str::FromStr; bitflags! { flags Flags: u32 { @@ -655,7 +656,7 @@ mod test { assert_eq!("hidden".parse::().unwrap(), AppSettings::Hidden); assert_eq!("dontdelimittrailingvalues".parse::().unwrap(), - AppSettings::DontDelimitTrailingValues); + AppSettings::DontDelimitTrailingValues); assert!("hahahaha".parse::().is_err()); } } diff --git a/src/args/any_arg.rs b/src/args/any_arg.rs index 91ffc7fa15d..6da4174ffe4 100644 --- a/src/args/any_arg.rs +++ b/src/args/any_arg.rs @@ -1,8 +1,11 @@ -use std::rc::Rc; +// Third Party -use vec_map::VecMap; + +// Internal use args::settings::ArgSettings; +use std::rc::Rc; +use vec_map::VecMap; #[doc(hidden)] pub trait AnyArg<'n, 'e> { diff --git a/src/args/arg_builder/flag.rs b/src/args/arg_builder/flag.rs index fef958fd784..55bd54b92ce 100644 --- a/src/args/arg_builder/flag.rs +++ b/src/args/arg_builder/flag.rs @@ -1,14 +1,18 @@ -// use std::collections::HashSet; -use std::fmt::{Display, Formatter, Result}; -use std::convert::From; -use std::rc::Rc; -use std::result::Result as StdResult; +// Std -use vec_map::VecMap; + +// Internal use Arg; use args::{AnyArg, DispOrder}; use args::settings::{ArgFlags, ArgSettings}; +use std::convert::From; +use std::fmt::{Display, Formatter, Result}; +use std::rc::Rc; +use std::result::Result as StdResult; + +// Third Party +use vec_map::VecMap; #[derive(Debug)] #[doc(hidden)] @@ -179,8 +183,8 @@ impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> { #[cfg(test)] mod test { - use super::FlagBuilder; use args::settings::ArgSettings; + use super::FlagBuilder; #[test] fn flagbuilder_display() { diff --git a/src/args/arg_builder/option.rs b/src/args/arg_builder/option.rs index 4b7c4195415..d99ad4ce29b 100644 --- a/src/args/arg_builder/option.rs +++ b/src/args/arg_builder/option.rs @@ -1,11 +1,16 @@ -use std::rc::Rc; -use std::fmt::{Display, Formatter, Result}; -use std::result::Result as StdResult; +// Std -use vec_map::VecMap; + +// Internal use args::{AnyArg, Arg, DispOrder}; use args::settings::{ArgFlags, ArgSettings}; +use std::fmt::{Display, Formatter, Result}; +use std::rc::Rc; +use std::result::Result as StdResult; + +// Third Party +use vec_map::VecMap; #[allow(missing_debug_implementations)] #[doc(hidden)] @@ -261,9 +266,9 @@ impl<'n, 'e> DispOrder for OptBuilder<'n, 'e> { #[cfg(test)] mod test { + use args::settings::ArgSettings; use super::OptBuilder; use vec_map::VecMap; - use args::settings::ArgSettings; #[test] fn optbuilder_display1() { diff --git a/src/args/arg_builder/positional.rs b/src/args/arg_builder/positional.rs index 8ea881d69d2..52baceaa7f7 100644 --- a/src/args/arg_builder/positional.rs +++ b/src/args/arg_builder/positional.rs @@ -1,13 +1,18 @@ -use std::fmt::{Display, Formatter, Result}; -use std::result::Result as StdResult; -use std::rc::Rc; -use std::borrow::Cow; +// Std -use vec_map::VecMap; + +// Internal use Arg; use args::{AnyArg, DispOrder}; use args::settings::{ArgFlags, ArgSettings}; +use std::borrow::Cow; +use std::fmt::{Display, Formatter, Result}; +use std::rc::Rc; +use std::result::Result as StdResult; + +// Third Party +use vec_map::VecMap; #[allow(missing_debug_implementations)] #[doc(hidden)] @@ -110,7 +115,7 @@ impl<'n, 'e> PosBuilder<'n, 'e> { pb } - pub fn multiple_str(&self) -> &str { + pub fn multiple_str(&self) -> &str { if self.settings.is_set(ArgSettings::Multiple) && self.val_names.is_none() { "..." } else { @@ -121,9 +126,9 @@ impl<'n, 'e> PosBuilder<'n, 'e> { pub fn name_no_brackets(&self) -> Cow { if let Some(ref names) = self.val_names { Cow::Owned(names.values() - .map(|n| format!("<{}>", n)) - .collect::>() - .join(" ")) + .map(|n| format!("<{}>", n)) + .collect::>() + .join(" ")) } else { Cow::Borrowed(self.name) } @@ -136,9 +141,9 @@ impl<'n, 'e> Display for PosBuilder<'n, 'e> { try!(write!(f, "{}", names.values() - .map(|n| format!("<{}>", n)) - .collect::>() - .join(" "))); + .map(|n| format!("<{}>", n)) + .collect::>() + .join(" "))); } else { try!(write!(f, "<{}>", self.name)); } @@ -251,8 +256,8 @@ impl<'n, 'e> DispOrder for PosBuilder<'n, 'e> { #[cfg(test)] mod test { - use super::PosBuilder; use args::settings::ArgSettings; + use super::PosBuilder; use vec_map::VecMap; #[test] diff --git a/src/args/arg_matcher.rs b/src/args/arg_matcher.rs index fe80a0eb128..daf7330c132 100644 --- a/src/args/arg_matcher.rs +++ b/src/args/arg_matcher.rs @@ -1,12 +1,17 @@ -use std::ffi::OsStr; -use std::collections::hash_map::{Entry, Iter}; -use std::ops::Deref; +// Std -use vec_map::VecMap; + +// Internal use args::{ArgMatches, MatchedArg, SubCommand}; -use args::settings::ArgSettings; use args::AnyArg; +use args::settings::ArgSettings; +use std::collections::hash_map::{Entry, Iter}; +use std::ffi::OsStr; +use std::ops::Deref; + +// Third Party +use vec_map::VecMap; #[doc(hidden)] #[allow(missing_debug_implementations)] diff --git a/src/args/arg_matches.rs b/src/args/arg_matches.rs index 945817208c4..e2821694ad4 100644 --- a/src/args/arg_matches.rs +++ b/src/args/arg_matches.rs @@ -1,15 +1,20 @@ -use std::ffi::{OsStr, OsString}; +// Std + + +// Internal + +use INVALID_UTF8; +use args::MatchedArg; +use args::SubCommand; +use std::borrow::Cow; use std::collections::HashMap; +use std::ffi::{OsStr, OsString}; use std::iter::Map; use std::slice; -use std::borrow::Cow; +// Third Party use vec_map; -use args::SubCommand; -use args::MatchedArg; -use INVALID_UTF8; - /// Used to get information about the arguments that where supplied to the program at runtime by /// the user. New instances of this struct are obtained by using the [`App::get_matches`] family of /// methods. @@ -242,9 +247,9 @@ impl<'a> ArgMatches<'a> { pub fn values_of_lossy>(&'a self, name: S) -> Option> { if let Some(arg) = self.args.get(name.as_ref()) { return Some(arg.vals - .values() - .map(|v| v.to_string_lossy().into_owned()) - .collect()); + .values() + .map(|v| v.to_string_lossy().into_owned()) + .collect()); } None } diff --git a/src/args/mod.rs b/src/args/mod.rs index 3bb1b3b24f8..337873a35b6 100644 --- a/src/args/mod.rs +++ b/src/args/mod.rs @@ -1,12 +1,13 @@ + +pub use self::any_arg::{AnyArg, DispOrder}; pub use self::arg::Arg; -pub use self::arg_matches::{Values, OsValues, ArgMatches}; -pub use self::arg_matcher::ArgMatcher; -pub use self::subcommand::SubCommand; pub use self::arg_builder::{FlagBuilder, OptBuilder, PosBuilder}; -pub use self::matched_arg::MatchedArg; +pub use self::arg_matcher::ArgMatcher; +pub use self::arg_matches::{Values, OsValues, ArgMatches}; pub use self::group::ArgGroup; -pub use self::any_arg::{AnyArg, DispOrder}; +pub use self::matched_arg::MatchedArg; pub use self::settings::ArgSettings; +pub use self::subcommand::SubCommand; #[macro_use] mod macros; diff --git a/src/args/settings.rs b/src/args/settings.rs index 4921fcd17d3..555b0181642 100644 --- a/src/args/settings.rs +++ b/src/args/settings.rs @@ -1,5 +1,7 @@ -use std::str::FromStr; +// Std + use std::ascii::AsciiExt; +use std::str::FromStr; bitflags! { flags Flags: u16 { diff --git a/src/completions.rs b/src/completions.rs index 7da92937c94..86e202c601f 100644 --- a/src/completions.rs +++ b/src/completions.rs @@ -1,8 +1,12 @@ -use std::io::Write; +// Std + + +// Internal use app::parser::Parser; -use shell::Shell; use args::{ArgSettings, OptBuilder}; +use shell::Shell; +use std::io::Write; macro_rules! w { ($buf:expr, $to_w:expr) => { @@ -13,15 +17,15 @@ macro_rules! w { }; } -pub struct ComplGen<'a, 'b> where 'a: 'b { +pub struct ComplGen<'a, 'b> + where 'a: 'b +{ p: &'b Parser<'a, 'b>, } impl<'a, 'b> ComplGen<'a, 'b> { pub fn new(p: &'b Parser<'a, 'b>) -> Self { - ComplGen { - p: p, - } + ComplGen { p: p } } pub fn generate(&self, for_shell: Shell, buf: &mut W) { @@ -32,8 +36,8 @@ impl<'a, 'b> ComplGen<'a, 'b> { } fn gen_bash(&self, buf: &mut W) { - w!(buf, format!( -"_{name}() {{ + w!(buf, + format!("_{name}() {{ local i cur prev opts cmds COMPREPLY=() cur=\"${{COMP_WORDS[COMP_CWORD]}}\" @@ -75,12 +79,13 @@ impl<'a, 'b> ComplGen<'a, 'b> { complete -F _{name} {name} ", - name=self.p.meta.bin_name.as_ref().unwrap(), - name_opts=self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()), - name_opts_details=self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()), - subcmds=self.all_subcommands(), - subcmd_details=self.subcommand_details() - ).as_bytes()); + name = self.p.meta.bin_name.as_ref().unwrap(), + name_opts = self.all_options_for_path(self.p.meta.bin_name.as_ref().unwrap()), + name_opts_details = + self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()), + subcmds = self.all_subcommands(), + subcmd_details = self.subcommand_details()) + .as_bytes()); } fn all_subcommands(&self) -> String { @@ -88,13 +93,12 @@ complete -F _{name} {name} let scs = get_all_subcommands(self.p); for sc in &scs { - subcmds = format!( - "{} + subcmds = format!("{} {name}) cmd+=\"_{name}\" ;;", - subcmds, - name=sc.replace("-", "_")); + subcmds, + name = sc.replace("-", "_")); } subcmds @@ -107,8 +111,7 @@ complete -F _{name} {name} scs.dedup(); for sc in &scs { - subcmd_dets = format!( - "{} + subcmd_dets = format!("{} {subcmd}) opts=\"{sc_opts}\" if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then @@ -124,12 +127,11 @@ complete -F _{name} {name} COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) ) return 0 ;;", - subcmd_dets, - subcmd=sc.replace("-", "_"), - sc_opts=self.all_options_for_path(&*sc), - level=sc.split("_").map(|_|1).fold(0, |acc, n| acc + n), - opts_details=self.option_details_for_path(&*sc) - ); + subcmd_dets, + subcmd = sc.replace("-", "_"), + sc_opts = self.all_options_for_path(&*sc), + level = sc.split("_").map(|_| 1).fold(0, |acc, n| acc + n), + opts_details = self.option_details_for_path(&*sc)); } subcmd_dets @@ -139,24 +141,45 @@ complete -F _{name} {name} let mut p = self.p; for sc in path.split('_').skip(1) { debugln!("iter;sc={}", sc); - p = &p.subcommands.iter() - .find(|s| s.p.meta.name == sc - || (s.p.meta.aliases.is_some() && s.p.meta.aliases.as_ref() - .unwrap() - .iter() - .any(|&(n,_)| n==sc ))) - .unwrap().p; + p = &p.subcommands + .iter() + .find(|s| { + s.p.meta.name == sc || + (s.p.meta.aliases.is_some() && + s.p + .meta + .aliases + .as_ref() + .unwrap() + .iter() + .any(|&(n, _)| n == sc)) + }) + .unwrap() + .p; } let mut opts = p.short_list.iter().fold(String::new(), |acc, s| format!("{} -{}", acc, s)); - opts = format!("{} {}", opts, p.long_list.iter() - .fold(String::new(), |acc, l| format!("{} --{}", acc, l))); - opts = format!("{} {}", opts, p.positionals.values() - .fold(String::new(), |acc, p| format!("{} {}", acc, p))); - opts = format!("{} {}", opts, p.subcommands.iter() - .fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name))); + opts = format!("{} {}", + opts, + p.long_list + .iter() + .fold(String::new(), |acc, l| format!("{} --{}", acc, l))); + opts = format!("{} {}", + opts, + p.positionals + .values() + .fold(String::new(), |acc, p| format!("{} {}", acc, p))); + opts = format!("{} {}", + opts, + p.subcommands + .iter() + .fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name))); for sc in &p.subcommands { if let Some(ref aliases) = sc.p.meta.aliases { - opts = format!("{} {}", opts, aliases.iter().map(|&(n,_)| n).fold(String::new(), |acc, a| format!("{} {}", acc, a))); + opts = format!("{} {}", + opts, + aliases.iter() + .map(|&(n, _)| n) + .fold(String::new(), |acc, a| format!("{} {}", acc, a))); } } opts @@ -166,14 +189,21 @@ complete -F _{name} {name} let mut p = self.p; for sc in path.split('_').skip(1) { debugln!("iter;sc={}", sc); - p = &p.subcommands.iter() - .find(|s| s.p.meta.name == sc || - (s.p.meta.aliases.is_some() && - s.p.meta.aliases.as_ref() - .unwrap() - .iter() - .any(|&(n,_)| n==sc ))) - .unwrap().p; + p = &p.subcommands + .iter() + .find(|s| { + s.p.meta.name == sc || + (s.p.meta.aliases.is_some() && + s.p + .meta + .aliases + .as_ref() + .unwrap() + .iter() + .any(|&(n, _)| n == sc)) + }) + .unwrap() + .p; } let mut opts = String::new(); for o in &p.opts { @@ -182,21 +212,27 @@ complete -F _{name} {name} --{}) COMPREPLY=({}) return 0 - ;;", opts, l, vals_for(o)); + ;;", + opts, + l, + vals_for(o)); } if let Some(s) = o.short { opts = format!("{} -{}) COMPREPLY=({}) return 0 - ;;", opts, s, vals_for(o)); + ;;", + opts, + s, + vals_for(o)); } } opts } fn gen_fish(&self, buf: &mut W) { - let command = self.p.meta.bin_name.as_ref().unwrap(); + let command = self.p.meta.bin_name.as_ref().unwrap(); let subcommands: Vec<_> = get_all_subcommands(self.p); let has_subcommands = subcommands.len() > 1; @@ -291,12 +327,10 @@ fn vals_for(o: &OptBuilder) -> String { } else if let Some(vec) = o.val_names() { let mut it = vec.iter().peekable(); while let Some((_, val)) = it.next() { - ret = format!("{}<{}>{}", ret, val, - if it.peek().is_some() { - " " - } else { - "" - }); + ret = format!("{}<{}>{}", + ret, + val, + if it.peek().is_some() { " " } else { "" }); } let num = vec.len(); if o.is_set(ArgSettings::Multiple) && num == 1 { @@ -305,12 +339,10 @@ fn vals_for(o: &OptBuilder) -> String { } else if let Some(num) = o.num_vals() { let mut it = (0..num).peekable(); while let Some(_) = it.next() { - ret = format!("{}<{}>{}", ret, o.name(), - if it.peek().is_some() { - " " - } else { - "" - }); + ret = format!("{}<{}>{}", + ret, + o.name(), + if it.peek().is_some() { " " } else { "" }); } if o.is_set(ArgSettings::Multiple) && num == 1 { ret = format!("{}...", ret); @@ -350,11 +382,11 @@ fn gen_fish_inner(root_command: &str, for option in &comp_gen.p.opts { let mut template = format!("complete -c {}", root_command); if !parent_cmds.is_empty() { - template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", - command).as_str()); + template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", command).as_str()); } else if has_no_subcommand_fn { template.push_str(format!(" -n '__fish_{}_no_subcommand'", - comp_gen.p.meta.bin_name.as_ref().unwrap()).as_str()); + comp_gen.p.meta.bin_name.as_ref().unwrap()) + .as_str()); } if let Some(data) = option.short { template.push_str(format!(" -s {}", data).as_str()); @@ -375,11 +407,11 @@ fn gen_fish_inner(root_command: &str, for flag in &comp_gen.p.flags { let mut template = format!("complete -c {}", root_command); if !parent_cmds.is_empty() { - template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", - command).as_str()); + template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", command).as_str()); } else if has_no_subcommand_fn { template.push_str(format!(" -n '__fish_{}_no_subcommand'", - comp_gen.p.meta.bin_name.as_ref().unwrap()).as_str()); + comp_gen.p.meta.bin_name.as_ref().unwrap()) + .as_str()); } if let Some(data) = flag.short { template.push_str(format!(" -s {}", data).as_str()); @@ -399,10 +431,12 @@ fn gen_fish_inner(root_command: &str, let mut template = format!("complete -c {}", root_command); if !parent_cmds.is_empty() { template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", - subcommand).as_str()); + subcommand) + .as_str()); } else if has_no_subcommand_fn { template.push_str(format!(" -n '__fish_{}_no_subcommand'", - comp_gen.p.meta.bin_name.as_ref().unwrap()).as_str()); + comp_gen.p.meta.bin_name.as_ref().unwrap()) + .as_str()); } template.push_str(" -f"); template.push_str(format!(" -a '{}'", subcommand).as_str()); diff --git a/src/errors.rs b/src/errors.rs index eded4856b96..be0f5113f26 100644 --- a/src/errors.rs +++ b/src/errors.rs @@ -1,14 +1,17 @@ -use std::process; +// Std + + +// Internal +use args::any_arg::AnyArg; +use fmt; +use std::convert::From; use std::error::Error as StdError; use std::fmt as std_fmt; use std::fmt::Display; use std::io::{self, Write}; -use std::convert::From; +use std::process; use std::result::Result as StdResult; - -use fmt; use suggestions; -use args::any_arg::AnyArg; /// Short hand for [`Result`] type /// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html @@ -383,7 +386,11 @@ impl Error { } #[doc(hidden)] - pub fn argument_conflict<'a, 'b, A, O, U>(arg: &A, other: Option, usage: U, color: fmt::ColorWhen) -> Self + pub fn argument_conflict<'a, 'b, A, O, U>(arg: &A, + other: Option, + usage: U, + color: fmt::ColorWhen) + -> Self where A: AnyArg<'a, 'b> + Display, O: Into, U: Display @@ -391,7 +398,7 @@ impl Error { let mut v = vec![arg.name().to_owned()]; let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The argument '{}' cannot be used with {}\n\n\ @@ -405,12 +412,15 @@ impl Error { v.push(n.clone()); c.warning(format!("'{}'", n)) } - None => c.none("one or more of the other specified arguments".to_owned()), + None => { + c.none("one or more of the other specified arguments" + .to_owned()) + } }, usage, c.good("--help")), kind: ErrorKind::ArgumentConflict, - info: Some(v) + info: Some(v), } } @@ -421,7 +431,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The argument '{}' requires a value but none was supplied\ @@ -438,7 +448,12 @@ impl Error { } #[doc(hidden)] - pub fn invalid_value<'a, 'b, B, G, A, U>(bad_val: B, good_vals: &[G], arg: &A, usage: U, color: fmt::ColorWhen) -> Self + pub fn invalid_value<'a, 'b, B, G, A, U>(bad_val: B, + good_vals: &[G], + arg: &A, + usage: U, + color: fmt::ColorWhen) + -> Self where B: AsRef, G: AsRef + Display, A: AnyArg<'a, 'b> + Display, @@ -446,7 +461,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; let suffix = suggestions::did_you_mean_suffix(bad_val.as_ref(), @@ -479,7 +494,12 @@ impl Error { } #[doc(hidden)] - pub fn invalid_subcommand(subcmd: S, did_you_mean: D, name: N, usage: U, color: fmt::ColorWhen) -> Self + pub fn invalid_subcommand(subcmd: S, + did_you_mean: D, + name: N, + usage: U, + color: fmt::ColorWhen) + -> Self where S: Into, D: AsRef + Display, N: Display, @@ -488,7 +508,7 @@ impl Error { let s = subcmd.into(); let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The subcommand '{}' wasn't recognized\n\t\ @@ -518,7 +538,7 @@ impl Error { let s = subcmd.into(); let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The subcommand '{}' wasn't recognized\n\n\ @@ -542,7 +562,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The following required arguments were not provided:{}\n\n\ @@ -564,7 +584,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} '{}' requires a subcommand, but one was not provided\n\n\ @@ -586,7 +606,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} Invalid UTF-8 was detected in one or more arguments\n\n\ @@ -601,7 +621,11 @@ impl Error { } #[doc(hidden)] - pub fn too_many_values<'a, 'b, V, A, U>(val: V, arg: &A, usage: U, color: fmt::ColorWhen) -> Self + pub fn too_many_values<'a, 'b, V, A, U>(val: V, + arg: &A, + usage: U, + color: fmt::ColorWhen) + -> Self where V: AsRef + Display + ToOwned, A: AnyArg<'a, 'b> + Display, U: Display @@ -609,7 +633,7 @@ impl Error { let v = val.as_ref(); let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The value '{}' was provided to '{}', but it wasn't expecting \ @@ -627,13 +651,18 @@ impl Error { } #[doc(hidden)] - pub fn too_few_values<'a, 'b, A, U>(arg: &A, min_vals: u64, curr_vals: usize, usage: U, color: fmt::ColorWhen) -> Self + pub fn too_few_values<'a, 'b, A, U>(arg: &A, + min_vals: u64, + curr_vals: usize, + usage: U, + color: fmt::ColorWhen) + -> Self where A: AnyArg<'a, 'b> + Display, U: Display { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The argument '{}' requires at least {} values, but only {} w{} \ @@ -644,11 +673,7 @@ impl Error { c.warning(arg.to_string()), c.warning(min_vals.to_string()), c.warning(curr_vals.to_string()), - if curr_vals > 1 { - "ere" - } else { - "as" - }, + if curr_vals > 1 { "ere" } else { "as" }, usage, c.good("--help")), kind: ErrorKind::TooFewValues, @@ -660,7 +685,7 @@ impl Error { pub fn value_validation(err: String, color: fmt::ColorWhen) -> Self { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} {}", c.error("error:"), err), @@ -679,7 +704,8 @@ impl Error { num_vals: u64, curr_vals: usize, suffix: S, - usage: U, color: fmt::ColorWhen) + usage: U, + color: fmt::ColorWhen) -> Self where A: AnyArg<'a, 'b> + Display, S: Display, @@ -687,7 +713,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The argument '{}' requires {} values, but {} w{} \ @@ -713,7 +739,7 @@ impl Error { { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} The argument '{}' was provided more than once, but cannot \ @@ -730,14 +756,18 @@ impl Error { } #[doc(hidden)] - pub fn unknown_argument(arg: A, did_you_mean: &str, usage: U, color: fmt::ColorWhen) -> Self + pub fn unknown_argument(arg: A, + did_you_mean: &str, + usage: U, + color: fmt::ColorWhen) + -> Self where A: Into, U: Display { let a = arg.into(); let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} Found argument '{}' which wasn't expected, or isn't valid in \ @@ -762,7 +792,7 @@ impl Error { pub fn io_error(e: &Error, color: fmt::ColorWhen) -> Self { let c = fmt::Colorizer { use_stderr: true, - when: color + when: color, }; Error { message: format!("{} {}", c.error("error:"), e.description()), @@ -778,7 +808,7 @@ impl Error { let a = arg.into(); let c = fmt::Colorizer { use_stderr: true, - when: fmt::ColorWhen::Auto + when: fmt::ColorWhen::Auto, }; Error { message: format!("{} The argument '{}' wasn't found", @@ -796,7 +826,7 @@ impl Error { pub fn with_description(description: &str, kind: ErrorKind) -> Self { let c = fmt::Colorizer { use_stderr: true, - when: fmt::ColorWhen::Auto + when: fmt::ColorWhen::Auto, }; Error { message: format!("{} {}", c.error("error:"), description), diff --git a/src/fmt.rs b/src/fmt.rs index f2afcba7d68..9e0a8d17642 100644 --- a/src/fmt.rs +++ b/src/fmt.rs @@ -1,12 +1,11 @@ -use std::fmt; +#[cfg(all(feature = "color", not(target_os = "windows")))] +use ansi_term::ANSIString; #[cfg(all(feature = "color", not(target_os = "windows")))] use ansi_term::Colour::{Green, Red, Yellow}; -#[cfg(all(feature = "color", not(target_os = "windows")))] -use ansi_term::ANSIString; #[cfg(feature = "color")] -use libc; +use libc;use std::fmt; #[cfg(all(feature = "color", not(target_os = "windows")))] const STDERR: i32 = libc::STDERR_FILENO; @@ -23,7 +22,7 @@ const STDOUT: i32 = 0; pub enum ColorWhen { Auto, Always, - Never + Never, } #[cfg(feature = "color")] @@ -43,7 +42,7 @@ pub fn is_a_tty(_: bool) -> bool { #[doc(hidden)] pub struct Colorizer { pub use_stderr: bool, - pub when: ColorWhen + pub when: ColorWhen, } macro_rules! color { @@ -61,22 +60,30 @@ macro_rules! color { } impl Colorizer { - pub fn good(&self, msg: T) -> Format where T: fmt::Display + AsRef { + pub fn good(&self, msg: T) -> Format + where T: fmt::Display + AsRef + { debugln!("exec=good;"); color!(self, Good, msg) } - pub fn warning(&self, msg: T) -> Format where T: fmt::Display + AsRef { + pub fn warning(&self, msg: T) -> Format + where T: fmt::Display + AsRef + { debugln!("exec=warning;"); color!(self, Warning, msg) } - pub fn error(&self, msg: T) -> Format where T: fmt::Display + AsRef { + pub fn error(&self, msg: T) -> Format + where T: fmt::Display + AsRef + { debugln!("exec=error;"); color!(self, Error, msg) } - pub fn none(&self, msg: T) -> Format where T: fmt::Display + AsRef { + pub fn none(&self, msg: T) -> Format + where T: fmt::Display + AsRef + { debugln!("exec=none;"); Format::None(msg) } @@ -86,7 +93,7 @@ impl Default for Colorizer { fn default() -> Self { Colorizer { use_stderr: true, - when: ColorWhen::Auto + when: ColorWhen::Auto, } } } @@ -147,9 +154,9 @@ impl fmt::Display for Format { #[cfg(all(test, feature = "color", not(target_os = "windows")))] mod test { - use super::Format; - use ansi_term::Colour::{Green, Red, Yellow}; use ansi_term::ANSIString; + use ansi_term::Colour::{Green, Red, Yellow}; + use super::Format; #[test] fn colored_output() { @@ -161,6 +168,7 @@ mod test { let warn = Format::Warning("warn"); assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn"))); let none = Format::None("none"); - assert_eq!(&*format!("{}", none), &*format!("{}", ANSIString::from("none"))); + assert_eq!(&*format!("{}", none), + &*format!("{}", ANSIString::from("none"))); } } diff --git a/src/osstringext.rs b/src/osstringext.rs index 9157558ba27..07c3401dd12 100644 --- a/src/osstringext.rs +++ b/src/osstringext.rs @@ -1,10 +1,8 @@ -use std::ffi::OsStr; +#[cfg(target_os = "windows")] +use INVALID_UTF8;use std::ffi::OsStr; #[cfg(not(target_os = "windows"))] use std::os::unix::ffi::OsStrExt; -#[cfg(target_os = "windows")] -use INVALID_UTF8; - #[cfg(target_os = "windows")] trait OsStrExt3 { fn from_bytes(b: &[u8]) -> &Self; diff --git a/src/usage_parser.rs b/src/usage_parser.rs index 8d2526b3afb..a55f01c0ebf 100644 --- a/src/usage_parser.rs +++ b/src/usage_parser.rs @@ -1,8 +1,12 @@ -use vec_map::VecMap; +// Third Party + + +// Internal +use INTERNAL_ERROR_MSG; use args::Arg; use args::settings::ArgSettings; -use INTERNAL_ERROR_MSG; +use vec_map::VecMap; type ParseResult = Result<(), ()>;