mirror of
https://github.com/clap-rs/clap
synced 2024-11-10 14:54:15 +00:00
style: rustfmt run
This commit is contained in:
parent
c6219ec5ed
commit
07e6e8ea31
18 changed files with 564 additions and 413 deletions
112
src/app/help.rs
112
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<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;");
|
||||
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::<Vec<_>>()
|
||||
.join(", "))
|
||||
.map(|v| format!("{}", self.cizer.good(v)))
|
||||
.collect::<Vec<_>>()
|
||||
.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::<Vec<_>>()
|
||||
.join(", ")
|
||||
} else {
|
||||
aliases.join(", ")
|
||||
});
|
||||
if self.color {
|
||||
aliases.iter()
|
||||
.map(|v| format!("{}", self.cizer.good(v)))
|
||||
.collect::<Vec<_>>()
|
||||
.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::<Vec<_>>()
|
||||
.join(", "))
|
||||
.map(|v| format!("{}", self.cizer.good(v)))
|
||||
.collect::<Vec<_>>()
|
||||
.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::<Vec<_>>())
|
||||
debugln!("iter;tag_buf={};", unsafe {
|
||||
String::from_utf8_unchecked(tag_buf.get_ref()[0..tag_length]
|
||||
.iter()
|
||||
.map(|&i| i)
|
||||
.collect::<Vec<_>>())
|
||||
});
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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()))
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -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> {
|
|||
/// `<project>/target/debug/build/myapp-<hash>/out/myapp.bash-completion`.
|
||||
///
|
||||
/// 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.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<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.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<Vec<&'e str>> {
|
||||
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 {
|
||||
|
|
|
@ -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<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));
|
||||
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<OsString> = 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 + [<reqs>] + 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::<Vec<_>>())
|
||||
.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::<Vec<_>>())
|
||||
}
|
||||
|
||||
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::<Vec<_>>();
|
||||
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::<Vec<_>>();
|
||||
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(" <SUBCOMMAND>");
|
||||
|
|
|
@ -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::<AppSettings>().unwrap(),
|
||||
AppSettings::Hidden);
|
||||
assert_eq!("dontdelimittrailingvalues".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::DontDelimitTrailingValues);
|
||||
AppSettings::DontDelimitTrailingValues);
|
||||
assert!("hahahaha".parse::<AppSettings>().is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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> {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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<str> {
|
||||
if let Some(ref names) = self.val_names {
|
||||
Cow::Owned(names.values()
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" "))
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.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::<Vec<_>>()
|
||||
.join(" ")));
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.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]
|
||||
|
|
|
@ -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)]
|
||||
|
|
|
@ -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<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> {
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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::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::subcommand::SubCommand;
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
use std::str::FromStr;
|
||||
// Std
|
||||
|
||||
use std::ascii::AsciiExt;
|
||||
use std::str::FromStr;
|
||||
|
||||
bitflags! {
|
||||
flags Flags: u16 {
|
||||
|
|
|
@ -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<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) {
|
||||
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<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 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());
|
||||
|
|
102
src/errors.rs
102
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<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,
|
||||
O: Into<String>,
|
||||
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<str>,
|
||||
G: AsRef<str> + 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<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>,
|
||||
D: AsRef<str> + 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<str> + 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<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>,
|
||||
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),
|
||||
|
|
38
src/fmt.rs
38
src/fmt.rs
|
@ -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")))]
|
||||
use ansi_term::ANSIString;
|
||||
|
||||
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
||||
use ansi_term::Colour::{Green, Red, Yellow};
|
||||
|
||||
#[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<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;");
|
||||
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;");
|
||||
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;");
|
||||
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;");
|
||||
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<T: fmt::Display> fmt::Display for Format<T> {
|
|||
|
||||
#[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")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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<(), ()>;
|
||||
|
||||
|
|
Loading…
Reference in a new issue