style: rustfmt run

This commit is contained in:
Kevin K 2016-09-05 15:29:40 -04:00
parent c6219ec5ed
commit 07e6e8ea31
18 changed files with 564 additions and 413 deletions

View file

@ -1,21 +1,24 @@
use std::io::{self, Cursor, Read, Write}; // Std
use std::collections::BTreeMap;
use std::fmt::Display;
use std::cmp;
use std::usize;
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::{App, AppSettings};
use app::parser::Parser; use app::parser::Parser;
use args::{AnyArg, ArgSettings, DispOrder};
use errors::{Error, Result as ClapResult};
use fmt::{Format, Colorizer}; 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")] #[cfg(feature = "wrap_help")]
use term_size; use term_size;
use unicode_segmentation::UnicodeSegmentation;
use vec_map::VecMap;
#[cfg(not(feature = "wrap_help"))] #[cfg(not(feature = "wrap_help"))]
mod term_size { mod term_size {
pub fn dimensions() -> Option<(usize, usize)> { pub fn dimensions() -> Option<(usize, usize)> {
@ -90,19 +93,21 @@ pub struct Help<'a> {
// Public Functions // Public Functions
impl<'a> Help<'a> { impl<'a> Help<'a> {
/// Create a new `Help` instance. /// 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<usize>) -> Self { pub fn new(w: &'a mut Write,
next_line_help: bool,
hide_pv: bool,
color: bool,
cizer: Colorizer,
term_w: Option<usize>)
-> Self {
debugln!("fn=Help::new;"); debugln!("fn=Help::new;");
Help { Help {
writer: w, writer: w,
next_line_help: next_line_help, next_line_help: next_line_help,
hide_pv: hide_pv, hide_pv: hide_pv,
term_w: match term_w { term_w: match term_w {
Some(width) => if width == 0 { Some(width) => if width == 0 { usize::MAX } else { width },
usize::MAX None => term_size::dimensions().map_or(120, |(w, _)| w),
} else {
width
},
None => term_size::dimensions().map_or(120, |(w, _)| w),
}, },
color: color, color: color,
cizer: cizer, cizer: cizer,
@ -312,7 +317,8 @@ impl<'a> Help<'a> {
let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp); let nlh = self.next_line_help || arg.is_set(ArgSettings::NextLineHelp);
let width = self.term_w; let width = self.term_w;
let taken = (longest + 12) + str_width(&*spec_vals); 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 arg.has_switch() {
if !(nlh || force_next_line) { 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 // We calculate with longest+12 since if it's already NLH we don't care
let taken = (longest + 12) + str_width(&*spec_vals); 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...{:?}", 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 { let spcs = if nlh || force_next_line {
8 // "tab" + "tab" 8 // "tab" + "tab"
@ -488,9 +498,9 @@ impl<'a> Help<'a> {
if self.color { if self.color {
format!(" [values: {}]", format!(" [values: {}]",
pv.iter() pv.iter()
.map(|v| format!("{}", self.cizer.good(v))) .map(|v| format!("{}", self.cizer.good(v)))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ")) .join(", "))
} else { } else {
format!(" [values: {}]", pv.join(", ")) format!(" [values: {}]", pv.join(", "))
} }
@ -501,14 +511,14 @@ impl<'a> Help<'a> {
} else if let Some(ref aliases) = a.aliases() { } else if let Some(ref aliases) = a.aliases() {
debugln!("Writing aliases"); debugln!("Writing aliases");
return format!(" [aliases: {}]", return format!(" [aliases: {}]",
if self.color { if self.color {
aliases.iter() aliases.iter()
.map(|v| format!("{}", self.cizer.good(v))) .map(|v| format!("{}", self.cizer.good(v)))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ") .join(", ")
} else { } else {
aliases.join(", ") aliases.join(", ")
}); });
} else if !self.hide_pv { } else if !self.hide_pv {
debugln!("Writing values"); debugln!("Writing values");
if let Some(pv) = a.possible_vals() { if let Some(pv) = a.possible_vals() {
@ -516,9 +526,9 @@ impl<'a> Help<'a> {
return if self.color { return if self.color {
format!(" [values: {}]", format!(" [values: {}]",
pv.iter() pv.iter()
.map(|v| format!("{}", self.cizer.good(v))) .map(|v| format!("{}", self.cizer.good(v)))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", ")) .join(", "))
} else { } else {
format!(" [values: {}]", pv.join(", ")) format!(" [values: {}]", pv.join(", "))
}; };
@ -547,8 +557,8 @@ impl<'a> Help<'a> {
if unified_help && (flags || opts) { if unified_help && (flags || opts) {
let opts_flags = parser.iter_flags() let opts_flags = parser.iter_flags()
.map(as_arg_trait) .map(as_arg_trait)
.chain(parser.iter_opts().map(as_arg_trait)); .chain(parser.iter_opts().map(as_arg_trait));
try!(color!(self, "OPTIONS:\n", warning)); try!(color!(self, "OPTIONS:\n", warning));
try!(self.write_args(opts_flags)); try!(self.write_args(opts_flags));
first = false; first = false;
@ -556,7 +566,7 @@ impl<'a> Help<'a> {
if flags { if flags {
try!(color!(self, "FLAGS:\n", warning)); try!(color!(self, "FLAGS:\n", warning));
try!(self.write_args(parser.iter_flags() try!(self.write_args(parser.iter_flags()
.map(as_arg_trait))); .map(as_arg_trait)));
first = false; first = false;
} }
if opts { if opts {
@ -826,11 +836,11 @@ impl<'a> Help<'a> {
_ => continue, _ => continue,
}; };
debugln!("iter;tag_buf={};", unsafe { debugln!("iter;tag_buf={};", unsafe {
String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length] String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length]
.iter() .iter()
.map(|&i|i) .map(|&i| i)
.collect::<Vec<_>>()) .collect::<Vec<_>>())
}); });
match &tag_buf.get_ref()[0..tag_length] { match &tag_buf.get_ref()[0..tag_length] {
b"?" => { b"?" => {
@ -862,21 +872,21 @@ impl<'a> Help<'a> {
} }
b"unified" => { b"unified" => {
let opts_flags = parser.iter_flags() let opts_flags = parser.iter_flags()
.map(as_arg_trait) .map(as_arg_trait)
.chain(parser.iter_opts().map(as_arg_trait)); .chain(parser.iter_opts().map(as_arg_trait));
try!(self.write_args(opts_flags)); try!(self.write_args(opts_flags));
} }
b"flags" => { b"flags" => {
try!(self.write_args(parser.iter_flags() try!(self.write_args(parser.iter_flags()
.map(as_arg_trait))); .map(as_arg_trait)));
} }
b"options" => { b"options" => {
try!(self.write_args(parser.iter_opts() try!(self.write_args(parser.iter_opts()
.map(as_arg_trait))); .map(as_arg_trait)));
} }
b"positionals" => { b"positionals" => {
try!(self.write_args(parser.iter_positionals() try!(self.write_args(parser.iter_positionals()
.map(as_arg_trait))); .map(as_arg_trait)));
} }
b"subcommands" => { b"subcommands" => {
try!(self.write_subcommands(&parser)); try!(self.write_subcommands(&parser));
@ -904,7 +914,9 @@ impl<'a> Help<'a> {
#[cfg_attr(feature = "lints", allow(explicit_counter_loop))] #[cfg_attr(feature = "lints", allow(explicit_counter_loop))]
fn wrap_help(help: &mut String, longest_w: usize, avail_chars: usize) { 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..."); debug!("Enough space to wrap...");
if longest_w < avail_chars { if longest_w < avail_chars {
sdebugln!("Yes"); sdebugln!("Yes");
@ -913,9 +925,11 @@ fn wrap_help(help: &mut String, longest_w: usize, avail_chars: usize) {
let mut i = 0; let mut i = 0;
for (idx, g) in (&*help.clone()).grapheme_indices(true) { for (idx, g) in (&*help.clone()).grapheme_indices(true) {
debugln!("iter;idx={},g={}", idx, g); debugln!("iter;idx={},g={}", idx, g);
if g != " " { continue; } if g != " " {
continue;
}
if str_width(&help[j..idx + (2 * i)]) < avail_chars { if str_width(&help[j..idx + (2 * i)]) < avail_chars {
debugln!("Still enough space..."); debugln!("Still enough space...");
prev_space = idx; prev_space = idx;
continue; continue;
} }

View file

@ -104,8 +104,10 @@ macro_rules! validate_multiples {
($_self:ident, $a:ident, $m:ident) => { ($_self:ident, $a:ident, $m:ident) => {
debugln!("macro=validate_multiples!;"); debugln!("macro=validate_multiples!;");
if $m.contains(&$a.name) && !$a.settings.is_set(ArgSettings::Multiple) { if $m.contains(&$a.name) && !$a.settings.is_set(ArgSettings::Multiple) {
// Not the first time, and we don't allow multiples // Not the first time, and we don't allow multiples
return Err(Error::unexpected_multiple_usage($a, &*$_self.create_current_usage($m), $_self.color())) return Err(Error::unexpected_multiple_usage($a,
&*$_self.create_current_usage($m),
$_self.color()))
} }
}; };
} }

View file

@ -6,28 +6,31 @@ pub mod parser;
mod meta; mod meta;
mod help; 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::env;
use std::ffi::OsString;
use std::fmt;
use std::io::{self, BufRead, BufWriter, Write}; use std::io::{self, BufRead, BufWriter, Write};
use std::path::Path; use std::path::Path;
use std::process; use std::process;
use std::ffi::OsString;
use std::borrow::Borrow;
use std::result::Result as StdResult;
use std::rc::Rc; use std::rc::Rc;
use std::fmt; use std::result::Result as StdResult;
// Third Party
use vec_map::VecMap;
#[cfg(feature = "yaml")] #[cfg(feature = "yaml")]
use yaml_rust::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 /// 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 /// arguments. Application settings are set using the "builder pattern" with the
@ -1086,7 +1089,10 @@ impl<'a, 'b> App<'a, 'b> {
/// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash-completion`. /// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash-completion`.
/// ///
/// Fish shell completions will use the file format `{bin_name}.fish` /// Fish shell completions will use the file format `{bin_name}.fish`
pub fn gen_completions<T: Into<OsString>, S: Into<String>>(&mut self, bin_name: S, for_shell: Shell, out_dir: T) { pub fn gen_completions<T: Into<OsString>, S: Into<String>>(&mut self,
bin_name: S,
for_shell: Shell,
out_dir: T) {
self.p.meta.bin_name = Some(bin_name.into()); self.p.meta.bin_name = Some(bin_name.into());
self.p.gen_completions(for_shell, out_dir.into()); self.p.gen_completions(for_shell, out_dir.into());
} }
@ -1124,7 +1130,10 @@ impl<'a, 'b> App<'a, 'b> {
/// ```shell /// ```shell
/// $ myapp generate-bash-completions > /etc/bash_completion.d/myapp /// $ myapp generate-bash-completions > /etc/bash_completion.d/myapp
/// ``` /// ```
pub fn gen_completions_to<W: Write, S: Into<String>>(&mut self, bin_name: S, for_shell: Shell, buf: &mut W) { pub fn gen_completions_to<W: Write, S: Into<String>>(&mut self,
bin_name: S,
for_shell: Shell,
buf: &mut W) {
self.p.meta.bin_name = Some(bin_name.into()); self.p.meta.bin_name = Some(bin_name.into());
self.p.gen_completions_to(for_shell, buf); 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()); is_sc = Some(yaml_hash.get(sc_key).unwrap());
App::new(sc_key.as_str().unwrap()) App::new(sc_key.as_str().unwrap())
}; };
yaml = if let Some(sc) = is_sc { yaml = if let Some(sc) = is_sc { sc } else { yaml };
sc
} else {
yaml
};
macro_rules! yaml_str { macro_rules! yaml_str {
($a:ident, $y:ident, $i:ident) => { ($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() { if let Some(v) = yaml["global_settings"].as_vec() {
for ys in v { for ys in v {
if let Some(s) = ys.as_str() { 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 { } else {
@ -1531,7 +1538,8 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
} }
fn aliases(&self) -> Option<Vec<&'e str>> { fn aliases(&self) -> Option<Vec<&'e str>> {
if let Some(ref aliases) = self.p.meta.aliases { 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() { if vis_aliases.is_empty() {
None None
} else { } else {

View file

@ -1,33 +1,38 @@
use std::collections::{BTreeMap, HashMap, VecDeque}; // Std
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;
use vec_map::{self, VecMap};
use app::help::Help; // Internal
use INTERNAL_ERROR_MSG;
use INVALID_UTF8;
use SubCommand;
use app::App; use app::App;
use args::{Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder}; use app::help::Help;
use app::meta::AppMeta;
use app::settings::{AppFlags, AppSettings}; use app::settings::{AppFlags, AppSettings};
use args::{AnyArg, ArgMatcher}; use args::{AnyArg, ArgMatcher};
use args::{Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder};
use args::MatchedArg;
use args::settings::ArgSettings; use args::settings::ArgSettings;
use completions::ComplGen;
use errors::{Error, ErrorKind}; use errors::{Error, ErrorKind};
use errors::Result as ClapResult; use errors::Result as ClapResult;
use INVALID_UTF8;
use suggestions;
use INTERNAL_ERROR_MSG;
use SubCommand;
use fmt::{Format, ColorWhen}; use fmt::{Format, ColorWhen};
use osstringext::OsStrExt2; use osstringext::OsStrExt2;
use app::meta::AppMeta;
use args::MatchedArg;
use shell::Shell; 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::fs::File;
use std::io::{self, BufWriter, Write};
#[cfg(feature = "debug")]
use std::os::unix::ffi::OsStrExt;
use std::path::PathBuf; use std::path::PathBuf;
use std::slice::Iter;
use suggestions;
// Third Party
use vec_map::{self, VecMap};
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]
#[doc(hidden)] #[doc(hidden)]
@ -91,14 +96,14 @@ impl<'a, 'b> Parser<'a, 'b>
pub fn help_short(&mut self, s: &str) { pub fn help_short(&mut self, s: &str) {
self.help_short = s.trim_left_matches(|c| c == '-') self.help_short = s.trim_left_matches(|c| c == '-')
.chars() .chars()
.nth(0); .nth(0);
} }
pub fn version_short(&mut self, s: &str) { pub fn version_short(&mut self, s: &str) {
self.version_short = s.trim_left_matches(|c| c == '-') self.version_short = s.trim_left_matches(|c| c == '-')
.chars() .chars()
.nth(0); .nth(0);
} }
pub fn gen_completions_to<W: Write>(&mut self, for_shell: Shell, buf: &mut W) { pub fn gen_completions_to<W: Write>(&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)); format!("Non-unique argument name: {} is already in use", a.name));
if let Some(ref grps) = a.group { if let Some(ref grps) = a.group {
for g in grps { for g in grps {
let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g)); let ag = self.groups.entry(g).or_insert_with(|| ArgGroup::with_name(g));
ag.args.push(a.name); ag.args.push(a.name);
} }
} }
if let Some(s) = a.short { if let Some(s) = a.short {
@ -248,7 +253,7 @@ impl<'a, 'b> Parser<'a, 'b>
self.meta.version.is_some() { self.meta.version.is_some() {
sdebugln!("Yes"); sdebugln!("Yes");
subcmd = subcmd.setting(AppSettings::GlobalVersion) subcmd = subcmd.setting(AppSettings::GlobalVersion)
.version(self.meta.version.unwrap()); .version(self.meta.version.unwrap());
} else { } else {
sdebugln!("No"); sdebugln!("No");
} }
@ -365,7 +370,7 @@ impl<'a, 'b> Parser<'a, 'b>
debugln!("args_in_groups={:?}", args_in_groups); debugln!("args_in_groups={:?}", args_in_groups);
for (_, s) in pmap { for (_, s) in pmap {
if (!args_in_groups.is_empty()) && (args_in_groups.contains(&&*s)) { if (!args_in_groups.is_empty()) && (args_in_groups.contains(&&*s)) {
continue; continue;
} }
ret_val.push_back(s); ret_val.push_back(s);
@ -385,7 +390,7 @@ impl<'a, 'b> Parser<'a, 'b>
let mut g_vec = vec![]; let mut g_vec = vec![];
for g in grps.into_iter() { for g in grps.into_iter() {
let g_string = self.args_in_group(g) let g_string = self.args_in_group(g)
.join("|"); .join("|");
g_vec.push(format!("<{}>", &g_string[..g_string.len()])); g_vec.push(format!("<{}>", &g_string[..g_string.len()]));
} }
g_vec.dedup(); g_vec.dedup();
@ -413,10 +418,10 @@ impl<'a, 'b> Parser<'a, 'b>
} }
} }
debugln!("Arg not required..."); debugln!("Arg not required...");
count +=1; count += 1;
} else { } else {
debugln!("Arg not required..."); debugln!("Arg not required...");
count +=1; count += 1;
} }
} }
if count > 1 || self.positionals.len() > 1 { if count > 1 || self.positionals.len() > 1 {
@ -578,14 +583,18 @@ impl<'a, 'b> Parser<'a, 'b>
if !self.trailing_vals { if !self.trailing_vals {
// Does the arg match a subcommand name, or any of it's aliases (if defined) // Does the arg match a subcommand name, or any of it's aliases (if defined)
let pos_sc = self.subcommands let pos_sc = self.subcommands
.iter() .iter()
.any(|s| &s.p.meta.name[..] == &*arg_os || .any(|s| {
(s.p.meta.aliases.is_some() && &s.p.meta.name[..] == &*arg_os ||
s.p.meta.aliases (s.p.meta.aliases.is_some() &&
.as_ref() s.p
.unwrap() .meta
.iter() .aliases
.any(|&(a, _)| a == &*arg_os))); .as_ref()
.unwrap()
.iter()
.any(|&(a, _)| a == &*arg_os))
});
if (!starts_new_arg || self.is_set(AppSettings::AllowLeadingHyphen)) && !pos_sc { if (!starts_new_arg || self.is_set(AppSettings::AllowLeadingHyphen)) && !pos_sc {
// Check to see if parsing a value from an option // Check to see if parsing a value from an option
if let Some(nvo) = needs_val_of { if let Some(nvo) = needs_val_of {
@ -622,36 +631,36 @@ impl<'a, 'b> Parser<'a, 'b>
let cmds: Vec<OsString> = it.map(|c| c.into()).collect(); let cmds: Vec<OsString> = it.map(|c| c.into()).collect();
let mut help_help = false; let mut help_help = false;
let mut bin_name = self.meta let mut bin_name = self.meta
.bin_name .bin_name
.as_ref() .as_ref()
.unwrap_or(&self.meta.name).clone(); .unwrap_or(&self.meta.name)
.clone();
let mut sc = { let mut sc = {
let mut sc: &Parser = self; let mut sc: &Parser = self;
for (i, cmd) in cmds.iter().enumerate() { 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; help_help = true;
} }
if let Some(c) = sc.subcommands if let Some(c) = sc.subcommands
.iter() .iter()
.find(|s| &*s.p.meta.name == cmd) .find(|s| &*s.p.meta.name == cmd)
.map(|sc| &sc.p) { .map(|sc| &sc.p) {
sc = c; sc = c;
if i == cmds.len() - 1 { if i == cmds.len() - 1 {
break; break;
} }
} else if let Some(c) = sc.subcommands } else if let Some(c) = sc.subcommands
.iter() .iter()
.find(|s| .find(|s| if let Some(ref als) = s.p
if let Some(ref als) = s.p .meta
.meta .aliases {
.aliases { als.iter()
als.iter() .any(|&(a, _)| &a == &&*cmd.to_string_lossy())
.any(|&(a, _)| &a == &&*cmd.to_string_lossy()) } else {
} else { false
false })
} .map(|sc| &sc.p) {
)
.map(|sc| &sc.p) {
sc = c; sc = c;
if i == cmds.len() - 1 { if i == cmds.len() - 1 {
break; break;
@ -691,9 +700,11 @@ impl<'a, 'b> Parser<'a, 'b>
subcmd_name = Some(arg_os.to_str().expect(INVALID_UTF8).to_owned()); subcmd_name = Some(arg_os.to_str().expect(INVALID_UTF8).to_owned());
break; break;
} else if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(), } else if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(),
self.subcommands self.subcommands
.iter() .iter()
.map(|s| &s.p.meta.name)) { .map(|s| {
&s.p.meta.name
})) {
return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(), return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
cdate, cdate,
self.meta self.meta
@ -713,9 +724,8 @@ impl<'a, 'b> Parser<'a, 'b>
Some(s) => s.to_string(), Some(s) => s.to_string(),
None => { None => {
if !self.settings.is_set(AppSettings::StrictUtf8) { if !self.settings.is_set(AppSettings::StrictUtf8) {
return Err( return Err(Error::invalid_utf8(&*self.create_current_usage(matcher),
Error::invalid_utf8(&*self.create_current_usage(matcher), self.color()) self.color()));
);
} }
arg_os.to_string_lossy().into_owned() arg_os.to_string_lossy().into_owned()
} }
@ -727,9 +737,8 @@ impl<'a, 'b> Parser<'a, 'b>
let a = v.into(); let a = v.into();
if let None = a.to_str() { if let None = a.to_str() {
if !self.settings.is_set(AppSettings::StrictUtf8) { if !self.settings.is_set(AppSettings::StrictUtf8) {
return Err( return Err(Error::invalid_utf8(&*self.create_current_usage(matcher),
Error::invalid_utf8(&*self.create_current_usage(matcher), self.color()) self.color()));
);
} }
} }
sc_m.add_val_to("", &a); sc_m.add_val_to("", &a);
@ -758,7 +767,9 @@ impl<'a, 'b> Parser<'a, 'b>
true true
}; };
if should_err { 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 { } else {
return Err(Error::empty_value(self.positionals return Err(Error::empty_value(self.positionals
@ -787,22 +798,26 @@ impl<'a, 'b> Parser<'a, 'b>
self.subcommands self.subcommands
.iter() .iter()
.filter(|sc| sc.p.meta.aliases.is_some()) .filter(|sc| sc.p.meta.aliases.is_some())
.filter_map(|sc| if sc.p.meta.aliases .filter_map(|sc| if sc.p
.as_ref() .meta
.unwrap() .aliases
.iter() .as_ref()
.any(|&(a, _)| &a == &&*pos_sc_name) { .unwrap()
Some(sc.p.meta.name.clone()) .iter()
} else { .any(|&(a, _)| &a == &&*pos_sc_name) {
None Some(sc.p.meta.name.clone())
}) } else {
None
})
.next() .next()
.expect(INTERNAL_ERROR_MSG) .expect(INTERNAL_ERROR_MSG)
}; };
try!(self.parse_subcommand(sc_name, matcher, it)); try!(self.parse_subcommand(sc_name, matcher, it));
} else if self.is_set(AppSettings::SubcommandRequired) { } else if self.is_set(AppSettings::SubcommandRequired) {
let bn = self.meta.bin_name.as_ref().unwrap_or(&self.meta.name); 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) { } else if self.is_set(AppSettings::SubcommandRequiredElseHelp) {
let mut out = vec![]; let mut out = vec![];
try!(self.write_help_err(&mut out)); try!(self.write_help_err(&mut out));
@ -884,8 +899,8 @@ impl<'a, 'b> Parser<'a, 'b>
} }
mid_string.push_str(" "); mid_string.push_str(" ");
if let Some(ref mut sc) = self.subcommands if let Some(ref mut sc) = self.subcommands
.iter_mut() .iter_mut()
.find(|s| &s.p.meta.name == &sc_name) { .find(|s| &s.p.meta.name == &sc_name) {
let mut sc_matcher = ArgMatcher::new(); let mut sc_matcher = ArgMatcher::new();
// bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by // bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by
// a space // a space
@ -1007,8 +1022,8 @@ impl<'a, 'b> Parser<'a, 'b>
} else if self.groups.contains_key(&**n) { } else if self.groups.contains_key(&**n) {
g_vec.push(*n); g_vec.push(*n);
} else if let Some(p) = self.positionals } else if let Some(p) = self.positionals
.values() .values()
.find(|p| &p.name == n) { .find(|p| &p.name == n) {
args.push(p.name.to_owned()); args.push(p.name.to_owned());
} }
} }
@ -1061,7 +1076,7 @@ impl<'a, 'b> Parser<'a, 'b>
self.flags.push(arg); self.flags.push(arg);
} }
if !self.settings.is_set(AppSettings::DisableVersion) && if !self.settings.is_set(AppSettings::DisableVersion) &&
self.is_set(AppSettings::NeedsLongVersion) { self.is_set(AppSettings::NeedsLongVersion) {
debugln!("Building --version"); debugln!("Building --version");
if self.version_short.is_none() && !self.short_list.contains(&'V') { if self.version_short.is_none() && !self.short_list.contains(&'V') {
self.version_short = Some('V'); self.version_short = Some('V');
@ -1084,7 +1099,7 @@ impl<'a, 'b> Parser<'a, 'b>
debugln!("Building help"); debugln!("Building help");
self.subcommands self.subcommands
.push(App::new("help") .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 // because those will be listed in self.required
pub fn create_current_usage(&self, matcher: &'b ArgMatcher<'a>) -> String { pub fn create_current_usage(&self, matcher: &'b ArgMatcher<'a>) -> String {
self.create_usage(&*matcher.arg_names() self.create_usage(&*matcher.arg_names()
.iter() .iter()
.filter(|n| { .filter(|n| {
if let Some(o) = self.opts if let Some(o) = self.opts
.iter() .iter()
.find(|&o| &&o.name == n) { .find(|&o| &&o.name == n) {
!o.settings.is_set(ArgSettings::Required) !o.settings.is_set(ArgSettings::Required)
} else if let Some(p) = self.positionals } else if let Some(p) = self.positionals
.values() .values()
.find(|&p| &&p.name == n) { .find(|&p| &&p.name == n) {
!p.settings.is_set(ArgSettings::Required) !p.settings.is_set(ArgSettings::Required)
} else { } else {
true // flags can't be required, so they're always true true // flags can't be required, so they're always true
} }
}) })
.map(|&n| n) .map(|&n| n)
.collect::<Vec<_>>()) .collect::<Vec<_>>())
} }
fn check_for_help_and_version_str(&self, arg: &OsStr) -> ClapResult<()> { 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 if let Some(opt) = self.opts
.iter() .iter()
.find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) {
debugln!("Found valid opt '{}'", opt.to_string()); debugln!("Found valid opt '{}'", opt.to_string());
let ret = try!(self.parse_opt(val, opt, matcher)); let ret = try!(self.parse_opt(val, opt, matcher));
arg_post_processing!(self, opt, matcher); arg_post_processing!(self, opt, matcher);
return Ok(ret); return Ok(ret);
} else if let Some(flag) = self.flags } else if let Some(flag) = self.flags
.iter() .iter()
.find(|v| v.long.is_some() && &*v.long.unwrap() == arg) { .find(|v| v.long.is_some() && &*v.long.unwrap() == arg) {
debugln!("Found valid flag '{}'", flag.to_string()); debugln!("Found valid flag '{}'", flag.to_string());
// Only flags could be help or version, and we need to check the raw long // Only flags could be help or version, and we need to check the raw long
// so this is the first point to check // so this is the first point to check
@ -1231,8 +1246,8 @@ impl<'a, 'b> Parser<'a, 'b>
// Option: -o // Option: -o
// Value: val // Value: val
if let Some(opt) = self.opts if let Some(opt) = self.opts
.iter() .iter()
.find(|&v| v.short.is_some() && v.short.unwrap() == c) { .find(|&v| v.short.is_some() && v.short.unwrap() == c) {
debugln!("Found valid short opt -{} in '{}'", c, arg); debugln!("Found valid short opt -{} in '{}'", c, arg);
// Check for trailing concatenated value // Check for trailing concatenated value
let p: Vec<_> = arg.splitn(2, c).collect(); let p: Vec<_> = arg.splitn(2, c).collect();
@ -1258,8 +1273,8 @@ impl<'a, 'b> Parser<'a, 'b>
return Ok(ret); return Ok(ret);
} else if let Some(flag) = self.flags } else if let Some(flag) = self.flags
.iter() .iter()
.find(|&v| v.short.is_some() && v.short.unwrap() == c) { .find(|&v| v.short.is_some() && v.short.unwrap() == c) {
debugln!("Found valid short flag -{}", c); debugln!("Found valid short flag -{}", c);
// Only flags can be help or version // Only flags can be help or version
try!(self.check_for_help_and_version_char(c)); 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'='); let v = fv.trim_left_matches(b'=');
if !opt.is_set(ArgSettings::EmptyValues) && v.len_() == 0 { if !opt.is_set(ArgSettings::EmptyValues) && v.len_() == 0 {
sdebugln!("Found Empty - Error"); 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_()); sdebugln!("Found - {:?}, len: {}", v, v.len_());
debugln!("{:?} contains '='...{:?}", fv, fv.starts_with(&[b'='])); debugln!("{:?} contains '='...{:?}", fv, fv.starts_with(&[b'=']));
@ -1308,7 +1325,8 @@ impl<'a, 'b> Parser<'a, 'b>
// Increment or create the group "args" // Increment or create the group "args"
self.groups_for_arg(opt.name).and_then(|vec| Some(matcher.inc_occurrences_of(&*vec))); 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)); return Ok(Some(opt.name));
} }
Ok(None) Ok(None)
@ -1332,7 +1350,8 @@ impl<'a, 'b> Parser<'a, 'b>
ret = try!(self.add_single_val_to_arg(arg, v, matcher)); 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 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; ret = None;
} }
} }
@ -1472,12 +1491,12 @@ impl<'a, 'b> Parser<'a, 'b>
if self.groups.contains_key(&**name) { if self.groups.contains_key(&**name) {
continue; continue;
} else if let Some(opt) = self.opts } else if let Some(opt) = self.opts
.iter() .iter()
.find(|o| &o.name == name) { .find(|o| &o.name == name) {
try!(self._validate_num_vals(opt, ma, matcher)); try!(self._validate_num_vals(opt, ma, matcher));
} else if let Some(pos) = self.positionals } else if let Some(pos) = self.positionals
.values() .values()
.find(|p| &p.name == name) { .find(|p| &p.name == name) {
try!(self._validate_num_vals(pos, ma, matcher)); 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 { if (ma.vals.len() as u64) > num {
debugln!("Sending error TooManyValues"); debugln!("Sending error TooManyValues");
return Err(Error::too_many_values(ma.vals return Err(Error::too_many_values(ma.vals
.get(ma.vals .get(ma.vals
.keys() .keys()
.last() .last()
.expect(INTERNAL_ERROR_MSG)) .expect(INTERNAL_ERROR_MSG))
.expect(INTERNAL_ERROR_MSG) .expect(INTERNAL_ERROR_MSG)
.to_str() .to_str()
.expect(INVALID_UTF8), .expect(INVALID_UTF8),
a, a,
&*self.create_current_usage(matcher), &*self.create_current_usage(matcher),
self.color())); self.color()));
@ -1575,21 +1594,21 @@ impl<'a, 'b> Parser<'a, 'b>
continue 'outer; continue 'outer;
} }
} }
let err = if self.settings.is_set(AppSettings::ArgRequiredElseHelp) && let err =
matcher.is_empty() { if self.settings.is_set(AppSettings::ArgRequiredElseHelp) && matcher.is_empty() {
self._help().unwrap_err() self._help().unwrap_err()
} else { } else {
let mut reqs = self.required.iter().map(|&r| &*r).collect::<Vec<_>>(); let mut reqs = self.required.iter().map(|&r| &*r).collect::<Vec<_>>();
reqs.retain(|n| !matcher.contains(n)); reqs.retain(|n| !matcher.contains(n));
reqs.dedup(); reqs.dedup();
Error::missing_required_argument( Error::missing_required_argument(
&*self.get_required_from(&*reqs, Some(matcher)) &*self.get_required_from(&*reqs, Some(matcher))
.iter() .iter()
.fold(String::new(), .fold(String::new(),
|acc, s| acc + &format!("\n {}", Format::Error(s))[..]), |acc, s| acc + &format!("\n {}", Format::Error(s))[..]),
&*self.create_current_usage(matcher), &*self.create_current_usage(matcher),
self.color()) self.color())
}; };
return Err(err); return Err(err);
} }
Ok(()) Ok(())
@ -1602,8 +1621,8 @@ impl<'a, 'b> Parser<'a, 'b>
for n in bl.iter() { for n in bl.iter() {
if matcher.contains(n) || if matcher.contains(n) ||
self.groups self.groups
.get(n) .get(n)
.map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) { .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
return true; return true;
} }
} }
@ -1612,15 +1631,15 @@ impl<'a, 'b> Parser<'a, 'b>
for n in ru.iter() { for n in ru.iter() {
if matcher.contains(n) || if matcher.contains(n) ||
self.groups self.groups
.get(n) .get(n)
.map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) { .map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
if !a.is_set(ArgSettings::RequiredUnlessAll) { if !a.is_set(ArgSettings::RequiredUnlessAll) {
return true; return true;
} }
found_any = true; found_any = true;
} else if a.is_set(ArgSettings::RequiredUnlessAll) { } else if a.is_set(ArgSettings::RequiredUnlessAll) {
return false; return false;
} }
} }
return found_any; 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 // Add the arg to the matches to build a proper usage string
if let Some(name) = suffix.1 { if let Some(name) = suffix.1 {
if let Some(opt) = self.opts if let Some(opt) = self.opts
.iter() .iter()
.find(|o| o.long.is_some() && o.long.unwrap() == name) { .find(|o| o.long.is_some() && o.long.unwrap() == name) {
self.groups_for_arg(&*opt.name) self.groups_for_arg(&*opt.name)
.and_then(|grps| Some(matcher.inc_occurrences_of(&*grps))); .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
matcher.insert(&*opt.name); matcher.insert(&*opt.name);
} else if let Some(flg) = self.flags } else if let Some(flg) = self.flags
.iter() .iter()
.find(|f| f.long.is_some() && f.long.unwrap() == name) { .find(|f| f.long.is_some() && f.long.unwrap() == name) {
self.groups_for_arg(&*flg.name) self.groups_for_arg(&*flg.name)
.and_then(|grps| Some(matcher.inc_occurrences_of(&*grps))); .and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
matcher.insert(&*flg.name); matcher.insert(&*flg.name);
@ -1652,7 +1671,10 @@ impl<'a, 'b> Parser<'a, 'b>
} }
let used_arg = format!("--{}", arg); 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 // 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); usage.push_str(&*u);
} else if used.is_empty() { } else if used.is_empty() {
usage.push_str(&*self.meta usage.push_str(&*self.meta
.usage .usage
.as_ref() .as_ref()
.unwrap_or(self.meta .unwrap_or(self.meta
.bin_name .bin_name
.as_ref() .as_ref()
.unwrap_or(&self.meta.name))); .unwrap_or(&self.meta.name)));
let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect(); let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect();
reqs.dedup(); reqs.dedup();
let req_string = self.get_required_from(&reqs, None) let req_string = self.get_required_from(&reqs, None)
.iter() .iter()
.fold(String::new(), |a, s| a + &format!(" {}", s)[..]); .fold(String::new(), |a, s| a + &format!(" {}", s)[..]);
let flags = self.needs_flags_tag(); let flags = self.needs_flags_tag();
if flags && !self.is_set(AppSettings::UnifiedHelpMessage) { if flags && !self.is_set(AppSettings::UnifiedHelpMessage) {
@ -1741,17 +1763,17 @@ impl<'a, 'b> Parser<'a, 'b>
hs.extend_from_slice(used); hs.extend_from_slice(used);
let r_string = self.get_required_from(&hs, None) let r_string = self.get_required_from(&hs, None)
.iter() .iter()
.fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]); .fold(String::new(), |acc, s| acc + &format!(" {}", s)[..]);
usage.push_str(&self.meta usage.push_str(&self.meta
.usage .usage
.as_ref() .as_ref()
.unwrap_or(self.meta .unwrap_or(self.meta
.bin_name .bin_name
.as_ref() .as_ref()
.unwrap_or(&self.meta .unwrap_or(&self.meta
.name))[..]); .name))[..]);
usage.push_str(&*r_string); usage.push_str(&*r_string);
if self.is_set(AppSettings::SubcommandRequired) { if self.is_set(AppSettings::SubcommandRequired) {
usage.push_str(" <SUBCOMMAND>"); usage.push_str(" <SUBCOMMAND>");

View file

@ -1,5 +1,6 @@
use std::str::FromStr;
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::str::FromStr;
bitflags! { bitflags! {
flags Flags: u32 { flags Flags: u32 {
@ -655,7 +656,7 @@ mod test {
assert_eq!("hidden".parse::<AppSettings>().unwrap(), assert_eq!("hidden".parse::<AppSettings>().unwrap(),
AppSettings::Hidden); AppSettings::Hidden);
assert_eq!("dontdelimittrailingvalues".parse::<AppSettings>().unwrap(), assert_eq!("dontdelimittrailingvalues".parse::<AppSettings>().unwrap(),
AppSettings::DontDelimitTrailingValues); AppSettings::DontDelimitTrailingValues);
assert!("hahahaha".parse::<AppSettings>().is_err()); assert!("hahahaha".parse::<AppSettings>().is_err());
} }
} }

View file

@ -1,8 +1,11 @@
use std::rc::Rc; // Third Party
use vec_map::VecMap;
// Internal
use args::settings::ArgSettings; use args::settings::ArgSettings;
use std::rc::Rc;
use vec_map::VecMap;
#[doc(hidden)] #[doc(hidden)]
pub trait AnyArg<'n, 'e> { pub trait AnyArg<'n, 'e> {

View file

@ -1,14 +1,18 @@
// use std::collections::HashSet; // Std
use std::fmt::{Display, Formatter, Result};
use std::convert::From;
use std::rc::Rc;
use std::result::Result as StdResult;
use vec_map::VecMap;
// Internal
use Arg; use Arg;
use args::{AnyArg, DispOrder}; use args::{AnyArg, DispOrder};
use args::settings::{ArgFlags, ArgSettings}; 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)] #[derive(Debug)]
#[doc(hidden)] #[doc(hidden)]
@ -179,8 +183,8 @@ impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::FlagBuilder;
use args::settings::ArgSettings; use args::settings::ArgSettings;
use super::FlagBuilder;
#[test] #[test]
fn flagbuilder_display() { fn flagbuilder_display() {

View file

@ -1,11 +1,16 @@
use std::rc::Rc; // Std
use std::fmt::{Display, Formatter, Result};
use std::result::Result as StdResult;
use vec_map::VecMap;
// Internal
use args::{AnyArg, Arg, DispOrder}; use args::{AnyArg, Arg, DispOrder};
use args::settings::{ArgFlags, ArgSettings}; 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)] #[allow(missing_debug_implementations)]
#[doc(hidden)] #[doc(hidden)]
@ -261,9 +266,9 @@ impl<'n, 'e> DispOrder for OptBuilder<'n, 'e> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use args::settings::ArgSettings;
use super::OptBuilder; use super::OptBuilder;
use vec_map::VecMap; use vec_map::VecMap;
use args::settings::ArgSettings;
#[test] #[test]
fn optbuilder_display1() { fn optbuilder_display1() {

View file

@ -1,13 +1,18 @@
use std::fmt::{Display, Formatter, Result}; // Std
use std::result::Result as StdResult;
use std::rc::Rc;
use std::borrow::Cow;
use vec_map::VecMap;
// Internal
use Arg; use Arg;
use args::{AnyArg, DispOrder}; use args::{AnyArg, DispOrder};
use args::settings::{ArgFlags, ArgSettings}; 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)] #[allow(missing_debug_implementations)]
#[doc(hidden)] #[doc(hidden)]
@ -110,7 +115,7 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
pb 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() { if self.settings.is_set(ArgSettings::Multiple) && self.val_names.is_none() {
"..." "..."
} else { } else {
@ -121,9 +126,9 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
pub fn name_no_brackets(&self) -> Cow<str> { pub fn name_no_brackets(&self) -> Cow<str> {
if let Some(ref names) = self.val_names { if let Some(ref names) = self.val_names {
Cow::Owned(names.values() Cow::Owned(names.values()
.map(|n| format!("<{}>", n)) .map(|n| format!("<{}>", n))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" ")) .join(" "))
} else { } else {
Cow::Borrowed(self.name) Cow::Borrowed(self.name)
} }
@ -136,9 +141,9 @@ impl<'n, 'e> Display for PosBuilder<'n, 'e> {
try!(write!(f, try!(write!(f,
"{}", "{}",
names.values() names.values()
.map(|n| format!("<{}>", n)) .map(|n| format!("<{}>", n))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(" "))); .join(" ")));
} else { } else {
try!(write!(f, "<{}>", self.name)); try!(write!(f, "<{}>", self.name));
} }
@ -251,8 +256,8 @@ impl<'n, 'e> DispOrder for PosBuilder<'n, 'e> {
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use super::PosBuilder;
use args::settings::ArgSettings; use args::settings::ArgSettings;
use super::PosBuilder;
use vec_map::VecMap; use vec_map::VecMap;
#[test] #[test]

View file

@ -1,12 +1,17 @@
use std::ffi::OsStr; // Std
use std::collections::hash_map::{Entry, Iter};
use std::ops::Deref;
use vec_map::VecMap;
// Internal
use args::{ArgMatches, MatchedArg, SubCommand}; use args::{ArgMatches, MatchedArg, SubCommand};
use args::settings::ArgSettings;
use args::AnyArg; 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)] #[doc(hidden)]
#[allow(missing_debug_implementations)] #[allow(missing_debug_implementations)]

View file

@ -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::collections::HashMap;
use std::ffi::{OsStr, OsString};
use std::iter::Map; use std::iter::Map;
use std::slice; use std::slice;
use std::borrow::Cow;
// Third Party
use vec_map; 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 /// 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 /// the user. New instances of this struct are obtained by using the [`App::get_matches`] family of
/// methods. /// methods.
@ -242,9 +247,9 @@ impl<'a> ArgMatches<'a> {
pub fn values_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> { pub fn values_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> {
if let Some(arg) = self.args.get(name.as_ref()) { if let Some(arg) = self.args.get(name.as_ref()) {
return Some(arg.vals return Some(arg.vals
.values() .values()
.map(|v| v.to_string_lossy().into_owned()) .map(|v| v.to_string_lossy().into_owned())
.collect()); .collect());
} }
None None
} }

View file

@ -1,12 +1,13 @@
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::group::ArgGroup;
pub use self::any_arg::{AnyArg, DispOrder}; pub use self::any_arg::{AnyArg, DispOrder};
pub use self::arg::Arg;
pub use self::arg_builder::{FlagBuilder, OptBuilder, PosBuilder};
pub use self::arg_matcher::ArgMatcher;
pub use self::arg_matches::{Values, OsValues, ArgMatches};
pub use self::group::ArgGroup;
pub use self::matched_arg::MatchedArg;
pub use self::settings::ArgSettings; pub use self::settings::ArgSettings;
pub use self::subcommand::SubCommand;
#[macro_use] #[macro_use]
mod macros; mod macros;

View file

@ -1,5 +1,7 @@
use std::str::FromStr; // Std
use std::ascii::AsciiExt; use std::ascii::AsciiExt;
use std::str::FromStr;
bitflags! { bitflags! {
flags Flags: u16 { flags Flags: u16 {

View file

@ -1,8 +1,12 @@
use std::io::Write; // Std
// Internal
use app::parser::Parser; use app::parser::Parser;
use shell::Shell;
use args::{ArgSettings, OptBuilder}; use args::{ArgSettings, OptBuilder};
use shell::Shell;
use std::io::Write;
macro_rules! w { macro_rules! w {
($buf:expr, $to_w:expr) => { ($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>, p: &'b Parser<'a, 'b>,
} }
impl<'a, 'b> ComplGen<'a, 'b> { impl<'a, 'b> ComplGen<'a, 'b> {
pub fn new(p: &'b Parser<'a, 'b>) -> Self { pub fn new(p: &'b Parser<'a, 'b>) -> Self {
ComplGen { ComplGen { p: p }
p: p,
}
} }
pub fn generate<W: Write>(&self, for_shell: Shell, buf: &mut W) { pub fn generate<W: Write>(&self, for_shell: Shell, buf: &mut W) {
@ -32,8 +36,8 @@ impl<'a, 'b> ComplGen<'a, 'b> {
} }
fn gen_bash<W: Write>(&self, buf: &mut W) { fn gen_bash<W: Write>(&self, buf: &mut W) {
w!(buf, format!( w!(buf,
"_{name}() {{ format!("_{name}() {{
local i cur prev opts cmds local i cur prev opts cmds
COMPREPLY=() COMPREPLY=()
cur=\"${{COMP_WORDS[COMP_CWORD]}}\" cur=\"${{COMP_WORDS[COMP_CWORD]}}\"
@ -75,12 +79,13 @@ impl<'a, 'b> ComplGen<'a, 'b> {
complete -F _{name} {name} complete -F _{name} {name}
", ",
name=self.p.meta.bin_name.as_ref().unwrap(), 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 = 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()), name_opts_details =
subcmds=self.all_subcommands(), self.option_details_for_path(self.p.meta.bin_name.as_ref().unwrap()),
subcmd_details=self.subcommand_details() subcmds = self.all_subcommands(),
).as_bytes()); subcmd_details = self.subcommand_details())
.as_bytes());
} }
fn all_subcommands(&self) -> String { fn all_subcommands(&self) -> String {
@ -88,13 +93,12 @@ complete -F _{name} {name}
let scs = get_all_subcommands(self.p); let scs = get_all_subcommands(self.p);
for sc in &scs { for sc in &scs {
subcmds = format!( subcmds = format!("{}
"{}
{name}) {name})
cmd+=\"_{name}\" cmd+=\"_{name}\"
;;", ;;",
subcmds, subcmds,
name=sc.replace("-", "_")); name = sc.replace("-", "_"));
} }
subcmds subcmds
@ -107,8 +111,7 @@ complete -F _{name} {name}
scs.dedup(); scs.dedup();
for sc in &scs { for sc in &scs {
subcmd_dets = format!( subcmd_dets = format!("{}
"{}
{subcmd}) {subcmd})
opts=\"{sc_opts}\" opts=\"{sc_opts}\"
if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then if [[ ${{cur}} == -* || ${{COMP_CWORD}} -eq {level} ]] ; then
@ -124,12 +127,11 @@ complete -F _{name} {name}
COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) ) COMPREPLY=( $(compgen -W \"${{opts}}\" -- ${{cur}}) )
return 0 return 0
;;", ;;",
subcmd_dets, subcmd_dets,
subcmd=sc.replace("-", "_"), subcmd = sc.replace("-", "_"),
sc_opts=self.all_options_for_path(&*sc), sc_opts = self.all_options_for_path(&*sc),
level=sc.split("_").map(|_|1).fold(0, |acc, n| acc + n), level = sc.split("_").map(|_| 1).fold(0, |acc, n| acc + n),
opts_details=self.option_details_for_path(&*sc) opts_details = self.option_details_for_path(&*sc));
);
} }
subcmd_dets subcmd_dets
@ -139,24 +141,45 @@ complete -F _{name} {name}
let mut p = self.p; let mut p = self.p;
for sc in path.split('_').skip(1) { for sc in path.split('_').skip(1) {
debugln!("iter;sc={}", sc); debugln!("iter;sc={}", sc);
p = &p.subcommands.iter() p = &p.subcommands
.find(|s| s.p.meta.name == sc .iter()
|| (s.p.meta.aliases.is_some() && s.p.meta.aliases.as_ref() .find(|s| {
.unwrap() s.p.meta.name == sc ||
.iter() (s.p.meta.aliases.is_some() &&
.any(|&(n,_)| n==sc ))) s.p
.unwrap().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)); let mut opts = p.short_list.iter().fold(String::new(), |acc, s| format!("{} -{}", acc, s));
opts = format!("{} {}", opts, p.long_list.iter() opts = format!("{} {}",
.fold(String::new(), |acc, l| format!("{} --{}", acc, l))); opts,
opts = format!("{} {}", opts, p.positionals.values() p.long_list
.fold(String::new(), |acc, p| format!("{} {}", acc, p))); .iter()
opts = format!("{} {}", opts, p.subcommands.iter() .fold(String::new(), |acc, l| format!("{} --{}", acc, l)));
.fold(String::new(), |acc, s| format!("{} {}", acc, s.p.meta.name))); 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 { for sc in &p.subcommands {
if let Some(ref aliases) = sc.p.meta.aliases { 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 opts
@ -166,14 +189,21 @@ complete -F _{name} {name}
let mut p = self.p; let mut p = self.p;
for sc in path.split('_').skip(1) { for sc in path.split('_').skip(1) {
debugln!("iter;sc={}", sc); debugln!("iter;sc={}", sc);
p = &p.subcommands.iter() p = &p.subcommands
.find(|s| s.p.meta.name == sc || .iter()
(s.p.meta.aliases.is_some() && .find(|s| {
s.p.meta.aliases.as_ref() s.p.meta.name == sc ||
.unwrap() (s.p.meta.aliases.is_some() &&
.iter() s.p
.any(|&(n,_)| n==sc ))) .meta
.unwrap().p; .aliases
.as_ref()
.unwrap()
.iter()
.any(|&(n, _)| n == sc))
})
.unwrap()
.p;
} }
let mut opts = String::new(); let mut opts = String::new();
for o in &p.opts { for o in &p.opts {
@ -182,21 +212,27 @@ complete -F _{name} {name}
--{}) --{})
COMPREPLY=({}) COMPREPLY=({})
return 0 return 0
;;", opts, l, vals_for(o)); ;;",
opts,
l,
vals_for(o));
} }
if let Some(s) = o.short { if let Some(s) = o.short {
opts = format!("{} opts = format!("{}
-{}) -{})
COMPREPLY=({}) COMPREPLY=({})
return 0 return 0
;;", opts, s, vals_for(o)); ;;",
opts,
s,
vals_for(o));
} }
} }
opts opts
} }
fn gen_fish<W: Write>(&self, buf: &mut W) { fn gen_fish<W: Write>(&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 subcommands: Vec<_> = get_all_subcommands(self.p);
let has_subcommands = subcommands.len() > 1; let has_subcommands = subcommands.len() > 1;
@ -291,12 +327,10 @@ fn vals_for(o: &OptBuilder) -> String {
} else if let Some(vec) = o.val_names() { } else if let Some(vec) = o.val_names() {
let mut it = vec.iter().peekable(); let mut it = vec.iter().peekable();
while let Some((_, val)) = it.next() { while let Some((_, val)) = it.next() {
ret = format!("{}<{}>{}", ret, val, ret = format!("{}<{}>{}",
if it.peek().is_some() { ret,
" " val,
} else { if it.peek().is_some() { " " } else { "" });
""
});
} }
let num = vec.len(); let num = vec.len();
if o.is_set(ArgSettings::Multiple) && num == 1 { 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() { } else if let Some(num) = o.num_vals() {
let mut it = (0..num).peekable(); let mut it = (0..num).peekable();
while let Some(_) = it.next() { while let Some(_) = it.next() {
ret = format!("{}<{}>{}", ret, o.name(), ret = format!("{}<{}>{}",
if it.peek().is_some() { ret,
" " o.name(),
} else { if it.peek().is_some() { " " } else { "" });
""
});
} }
if o.is_set(ArgSettings::Multiple) && num == 1 { if o.is_set(ArgSettings::Multiple) && num == 1 {
ret = format!("{}...", ret); ret = format!("{}...", ret);
@ -350,11 +382,11 @@ fn gen_fish_inner(root_command: &str,
for option in &comp_gen.p.opts { for option in &comp_gen.p.opts {
let mut template = format!("complete -c {}", root_command); let mut template = format!("complete -c {}", root_command);
if !parent_cmds.is_empty() { if !parent_cmds.is_empty() {
template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", command).as_str());
command).as_str());
} else if has_no_subcommand_fn { } else if has_no_subcommand_fn {
template.push_str(format!(" -n '__fish_{}_no_subcommand'", 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 { if let Some(data) = option.short {
template.push_str(format!(" -s {}", data).as_str()); 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 { for flag in &comp_gen.p.flags {
let mut template = format!("complete -c {}", root_command); let mut template = format!("complete -c {}", root_command);
if !parent_cmds.is_empty() { if !parent_cmds.is_empty() {
template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", command).as_str());
command).as_str());
} else if has_no_subcommand_fn { } else if has_no_subcommand_fn {
template.push_str(format!(" -n '__fish_{}_no_subcommand'", 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 { if let Some(data) = flag.short {
template.push_str(format!(" -s {}", data).as_str()); 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); let mut template = format!("complete -c {}", root_command);
if !parent_cmds.is_empty() { if !parent_cmds.is_empty() {
template.push_str(format!(" -n '__fish_seen_subcommand_from {}'", template.push_str(format!(" -n '__fish_seen_subcommand_from {}'",
subcommand).as_str()); subcommand)
.as_str());
} else if has_no_subcommand_fn { } else if has_no_subcommand_fn {
template.push_str(format!(" -n '__fish_{}_no_subcommand'", 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(" -f");
template.push_str(format!(" -a '{}'", subcommand).as_str()); template.push_str(format!(" -a '{}'", subcommand).as_str());

View file

@ -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::error::Error as StdError;
use std::fmt as std_fmt; use std::fmt as std_fmt;
use std::fmt::Display; use std::fmt::Display;
use std::io::{self, Write}; use std::io::{self, Write};
use std::convert::From; use std::process;
use std::result::Result as StdResult; use std::result::Result as StdResult;
use fmt;
use suggestions; use suggestions;
use args::any_arg::AnyArg;
/// Short hand for [`Result`] type /// Short hand for [`Result`] type
/// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html /// [`Result`]: https://doc.rust-lang.org/std/result/enum.Result.html
@ -383,7 +386,11 @@ impl Error {
} }
#[doc(hidden)] #[doc(hidden)]
pub fn argument_conflict<'a, 'b, A, O, U>(arg: &A, other: Option<O>, usage: U, color: fmt::ColorWhen) -> Self pub fn argument_conflict<'a, 'b, A, O, U>(arg: &A,
other: Option<O>,
usage: U,
color: fmt::ColorWhen)
-> Self
where A: AnyArg<'a, 'b> + Display, where A: AnyArg<'a, 'b> + Display,
O: Into<String>, O: Into<String>,
U: Display U: Display
@ -391,7 +398,7 @@ impl Error {
let mut v = vec![arg.name().to_owned()]; let mut v = vec![arg.name().to_owned()];
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The argument '{}' cannot be used with {}\n\n\ message: format!("{} The argument '{}' cannot be used with {}\n\n\
@ -405,12 +412,15 @@ impl Error {
v.push(n.clone()); v.push(n.clone());
c.warning(format!("'{}'", n)) 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, usage,
c.good("--help")), c.good("--help")),
kind: ErrorKind::ArgumentConflict, kind: ErrorKind::ArgumentConflict,
info: Some(v) info: Some(v),
} }
} }
@ -421,7 +431,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The argument '{}' requires a value but none was supplied\ message: format!("{} The argument '{}' requires a value but none was supplied\
@ -438,7 +448,12 @@ impl Error {
} }
#[doc(hidden)] #[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<str>, where B: AsRef<str>,
G: AsRef<str> + Display, G: AsRef<str> + Display,
A: AnyArg<'a, 'b> + Display, A: AnyArg<'a, 'b> + Display,
@ -446,7 +461,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
let suffix = let suffix =
suggestions::did_you_mean_suffix(bad_val.as_ref(), suggestions::did_you_mean_suffix(bad_val.as_ref(),
@ -479,7 +494,12 @@ impl Error {
} }
#[doc(hidden)] #[doc(hidden)]
pub fn invalid_subcommand<S, D, N, U>(subcmd: S, did_you_mean: D, name: N, usage: U, color: fmt::ColorWhen) -> Self pub fn invalid_subcommand<S, D, N, U>(subcmd: S,
did_you_mean: D,
name: N,
usage: U,
color: fmt::ColorWhen)
-> Self
where S: Into<String>, where S: Into<String>,
D: AsRef<str> + Display, D: AsRef<str> + Display,
N: Display, N: Display,
@ -488,7 +508,7 @@ impl Error {
let s = subcmd.into(); let s = subcmd.into();
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The subcommand '{}' wasn't recognized\n\t\ message: format!("{} The subcommand '{}' wasn't recognized\n\t\
@ -518,7 +538,7 @@ impl Error {
let s = subcmd.into(); let s = subcmd.into();
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The subcommand '{}' wasn't recognized\n\n\ message: format!("{} The subcommand '{}' wasn't recognized\n\n\
@ -542,7 +562,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The following required arguments were not provided:{}\n\n\ message: format!("{} The following required arguments were not provided:{}\n\n\
@ -564,7 +584,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} '{}' requires a subcommand, but one was not provided\n\n\ message: format!("{} '{}' requires a subcommand, but one was not provided\n\n\
@ -586,7 +606,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} Invalid UTF-8 was detected in one or more arguments\n\n\ message: format!("{} Invalid UTF-8 was detected in one or more arguments\n\n\
@ -601,7 +621,11 @@ impl Error {
} }
#[doc(hidden)] #[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<str> + Display + ToOwned, where V: AsRef<str> + Display + ToOwned,
A: AnyArg<'a, 'b> + Display, A: AnyArg<'a, 'b> + Display,
U: Display U: Display
@ -609,7 +633,7 @@ impl Error {
let v = val.as_ref(); let v = val.as_ref();
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The value '{}' was provided to '{}', but it wasn't expecting \ message: format!("{} The value '{}' was provided to '{}', but it wasn't expecting \
@ -627,13 +651,18 @@ impl Error {
} }
#[doc(hidden)] #[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, where A: AnyArg<'a, 'b> + Display,
U: Display U: Display
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The argument '{}' requires at least {} values, but only {} w{} \ message: format!("{} The argument '{}' requires at least {} values, but only {} w{} \
@ -644,11 +673,7 @@ impl Error {
c.warning(arg.to_string()), c.warning(arg.to_string()),
c.warning(min_vals.to_string()), c.warning(min_vals.to_string()),
c.warning(curr_vals.to_string()), c.warning(curr_vals.to_string()),
if curr_vals > 1 { if curr_vals > 1 { "ere" } else { "as" },
"ere"
} else {
"as"
},
usage, usage,
c.good("--help")), c.good("--help")),
kind: ErrorKind::TooFewValues, kind: ErrorKind::TooFewValues,
@ -660,7 +685,7 @@ impl Error {
pub fn value_validation(err: String, color: fmt::ColorWhen) -> Self { pub fn value_validation(err: String, color: fmt::ColorWhen) -> Self {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} {}", c.error("error:"), err), message: format!("{} {}", c.error("error:"), err),
@ -679,7 +704,8 @@ impl Error {
num_vals: u64, num_vals: u64,
curr_vals: usize, curr_vals: usize,
suffix: S, suffix: S,
usage: U, color: fmt::ColorWhen) usage: U,
color: fmt::ColorWhen)
-> Self -> Self
where A: AnyArg<'a, 'b> + Display, where A: AnyArg<'a, 'b> + Display,
S: Display, S: Display,
@ -687,7 +713,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The argument '{}' requires {} values, but {} w{} \ message: format!("{} The argument '{}' requires {} values, but {} w{} \
@ -713,7 +739,7 @@ impl Error {
{ {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} The argument '{}' was provided more than once, but cannot \ message: format!("{} The argument '{}' was provided more than once, but cannot \
@ -730,14 +756,18 @@ impl Error {
} }
#[doc(hidden)] #[doc(hidden)]
pub fn unknown_argument<A, U>(arg: A, did_you_mean: &str, usage: U, color: fmt::ColorWhen) -> Self pub fn unknown_argument<A, U>(arg: A,
did_you_mean: &str,
usage: U,
color: fmt::ColorWhen)
-> Self
where A: Into<String>, where A: Into<String>,
U: Display U: Display
{ {
let a = arg.into(); let a = arg.into();
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} Found argument '{}' which wasn't expected, or isn't valid in \ 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 { pub fn io_error(e: &Error, color: fmt::ColorWhen) -> Self {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: color when: color,
}; };
Error { Error {
message: format!("{} {}", c.error("error:"), e.description()), message: format!("{} {}", c.error("error:"), e.description()),
@ -778,7 +808,7 @@ impl Error {
let a = arg.into(); let a = arg.into();
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: fmt::ColorWhen::Auto when: fmt::ColorWhen::Auto,
}; };
Error { Error {
message: format!("{} The argument '{}' wasn't found", message: format!("{} The argument '{}' wasn't found",
@ -796,7 +826,7 @@ impl Error {
pub fn with_description(description: &str, kind: ErrorKind) -> Self { pub fn with_description(description: &str, kind: ErrorKind) -> Self {
let c = fmt::Colorizer { let c = fmt::Colorizer {
use_stderr: true, use_stderr: true,
when: fmt::ColorWhen::Auto when: fmt::ColorWhen::Auto,
}; };
Error { Error {
message: format!("{} {}", c.error("error:"), description), message: format!("{} {}", c.error("error:"), description),

View file

@ -1,12 +1,11 @@
use std::fmt;
#[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::Colour::{Green, Red, Yellow};
#[cfg(all(feature = "color", not(target_os = "windows")))] #[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::ANSIString; use ansi_term::ANSIString;
#[cfg(all(feature = "color", not(target_os = "windows")))]
use ansi_term::Colour::{Green, Red, Yellow};
#[cfg(feature = "color")] #[cfg(feature = "color")]
use libc; use libc;use std::fmt;
#[cfg(all(feature = "color", not(target_os = "windows")))] #[cfg(all(feature = "color", not(target_os = "windows")))]
const STDERR: i32 = libc::STDERR_FILENO; const STDERR: i32 = libc::STDERR_FILENO;
@ -23,7 +22,7 @@ const STDOUT: i32 = 0;
pub enum ColorWhen { pub enum ColorWhen {
Auto, Auto,
Always, Always,
Never Never,
} }
#[cfg(feature = "color")] #[cfg(feature = "color")]
@ -43,7 +42,7 @@ pub fn is_a_tty(_: bool) -> bool {
#[doc(hidden)] #[doc(hidden)]
pub struct Colorizer { pub struct Colorizer {
pub use_stderr: bool, pub use_stderr: bool,
pub when: ColorWhen pub when: ColorWhen,
} }
macro_rules! color { macro_rules! color {
@ -61,22 +60,30 @@ macro_rules! color {
} }
impl Colorizer { impl Colorizer {
pub fn good<T>(&self, msg: T) -> Format<T> where T: fmt::Display + AsRef<str> { pub fn good<T>(&self, msg: T) -> Format<T>
where T: fmt::Display + AsRef<str>
{
debugln!("exec=good;"); debugln!("exec=good;");
color!(self, Good, msg) color!(self, Good, msg)
} }
pub fn warning<T>(&self, msg: T) -> Format<T> where T: fmt::Display + AsRef<str> { pub fn warning<T>(&self, msg: T) -> Format<T>
where T: fmt::Display + AsRef<str>
{
debugln!("exec=warning;"); debugln!("exec=warning;");
color!(self, Warning, msg) color!(self, Warning, msg)
} }
pub fn error<T>(&self, msg: T) -> Format<T> where T: fmt::Display + AsRef<str> { pub fn error<T>(&self, msg: T) -> Format<T>
where T: fmt::Display + AsRef<str>
{
debugln!("exec=error;"); debugln!("exec=error;");
color!(self, Error, msg) color!(self, Error, msg)
} }
pub fn none<T>(&self, msg: T) -> Format<T> where T: fmt::Display + AsRef<str> { pub fn none<T>(&self, msg: T) -> Format<T>
where T: fmt::Display + AsRef<str>
{
debugln!("exec=none;"); debugln!("exec=none;");
Format::None(msg) Format::None(msg)
} }
@ -86,7 +93,7 @@ impl Default for Colorizer {
fn default() -> Self { fn default() -> Self {
Colorizer { Colorizer {
use_stderr: true, use_stderr: true,
when: ColorWhen::Auto when: ColorWhen::Auto,
} }
} }
} }
@ -147,9 +154,9 @@ impl<T: fmt::Display> fmt::Display for Format<T> {
#[cfg(all(test, feature = "color", not(target_os = "windows")))] #[cfg(all(test, feature = "color", not(target_os = "windows")))]
mod test { mod test {
use super::Format;
use ansi_term::Colour::{Green, Red, Yellow};
use ansi_term::ANSIString; use ansi_term::ANSIString;
use ansi_term::Colour::{Green, Red, Yellow};
use super::Format;
#[test] #[test]
fn colored_output() { fn colored_output() {
@ -161,6 +168,7 @@ mod test {
let warn = Format::Warning("warn"); let warn = Format::Warning("warn");
assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn"))); assert_eq!(&*format!("{}", warn), &*format!("{}", Yellow.paint("warn")));
let none = Format::None("none"); let none = Format::None("none");
assert_eq!(&*format!("{}", none), &*format!("{}", ANSIString::from("none"))); assert_eq!(&*format!("{}", none),
&*format!("{}", ANSIString::from("none")));
} }
} }

View file

@ -1,10 +1,8 @@
use std::ffi::OsStr; #[cfg(target_os = "windows")]
use INVALID_UTF8;use std::ffi::OsStr;
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]
use std::os::unix::ffi::OsStrExt; use std::os::unix::ffi::OsStrExt;
#[cfg(target_os = "windows")]
use INVALID_UTF8;
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
trait OsStrExt3 { trait OsStrExt3 {
fn from_bytes(b: &[u8]) -> &Self; fn from_bytes(b: &[u8]) -> &Self;

View file

@ -1,8 +1,12 @@
use vec_map::VecMap; // Third Party
// Internal
use INTERNAL_ERROR_MSG;
use args::Arg; use args::Arg;
use args::settings::ArgSettings; use args::settings::ArgSettings;
use INTERNAL_ERROR_MSG; use vec_map::VecMap;
type ParseResult = Result<(), ()>; type ParseResult = Result<(), ()>;