mirror of
https://github.com/clap-rs/clap
synced 2025-03-04 23:37:32 +00:00
commit
cff94579c1
25 changed files with 1142 additions and 668 deletions
|
@ -2,7 +2,7 @@ sudo: false
|
|||
language: rust
|
||||
rust:
|
||||
- nightly
|
||||
- nightly-2016-04-07
|
||||
- nightly-2016-04-28
|
||||
- beta
|
||||
- stable
|
||||
# Only while clippy is failing
|
||||
|
|
|
@ -18,7 +18,7 @@ libc = { version = "~0.2.9", optional = true }
|
|||
ansi_term = { version = "~0.7.2", optional = true }
|
||||
strsim = { version = "~0.4.0", optional = true }
|
||||
yaml-rust = { version = "~0.3.2", optional = true }
|
||||
clippy = { version = "=0.0.63", optional = true }
|
||||
clippy = { version = "=0.0.64", optional = true }
|
||||
unicode-width = { version = "~0.1.3", optional = true }
|
||||
|
||||
[features]
|
||||
|
|
|
@ -302,8 +302,8 @@ impl<'a> Help<'a> {
|
|||
// determine if our help fits or needs to wrap
|
||||
let width = self.term_w.unwrap_or(0);
|
||||
debugln!("Term width...{}", width);
|
||||
let too_long = self.term_w.is_some() && (spcs + str_width(h) +
|
||||
str_width(&*spec_vals) >= width);
|
||||
let too_long = self.term_w.is_some() &&
|
||||
(spcs + str_width(h) + str_width(&*spec_vals) >= width);
|
||||
debugln!("Too long...{:?}", too_long);
|
||||
|
||||
// Is help on next line, if so newline + 2x tab
|
||||
|
@ -403,33 +403,41 @@ impl<'a> Help<'a> {
|
|||
if let Some(ref pv) = a.default_val() {
|
||||
debugln!("Writing defaults");
|
||||
return format!(" [default: {}] {}",
|
||||
if self.color {
|
||||
format!("{}", Format::Good(pv))
|
||||
} else {
|
||||
format!("{}", pv)
|
||||
},
|
||||
if self.hide_pv {
|
||||
if self.color {
|
||||
format!("{}", Format::Good(pv))
|
||||
} else {
|
||||
pv.to_string()
|
||||
},
|
||||
if self.hide_pv {
|
||||
"".into()
|
||||
} else {
|
||||
if let Some(ref pv) = a.possible_vals() {
|
||||
if self.color {
|
||||
format!(" [values: {}]", pv.iter().map(|v| format!("{}", Format::Good(v))).collect::<Vec<_>>().join(", "))
|
||||
} else {
|
||||
format!(" [values: {}]", pv.join(", "))
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
if let Some(ref pv) = a.possible_vals() {
|
||||
if self.color {
|
||||
format!(" [values: {}]",
|
||||
pv.iter()
|
||||
.map(|v| format!("{}", Format::Good(v)))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "))
|
||||
} else {
|
||||
format!(" [values: {}]", pv.join(", "))
|
||||
}
|
||||
} else {
|
||||
"".into()
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} else if !self.hide_pv {
|
||||
debugln!("Writing values");
|
||||
if let Some(ref pv) = a.possible_vals() {
|
||||
debugln!("Possible vals...{:?}", pv);
|
||||
return if self.color {
|
||||
format!(" [values: {}]", pv.iter().map(|v| format!("{}", Format::Good(v))).collect::<Vec<_>>().join(", "))
|
||||
} else {
|
||||
format!(" [values: {}]", pv.join(", "))
|
||||
};
|
||||
return if self.color {
|
||||
format!(" [values: {}]",
|
||||
pv.iter()
|
||||
.map(|v| format!("{}", Format::Good(v)))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", "))
|
||||
} else {
|
||||
format!(" [values: {}]", pv.join(", "))
|
||||
};
|
||||
}
|
||||
}
|
||||
String::new()
|
||||
|
@ -552,7 +560,8 @@ impl<'a> Help<'a> {
|
|||
}
|
||||
|
||||
try!(color!(self, "\nUSAGE:", Warning));
|
||||
try!(write!(self.writer, "\n{}{}\n\n",
|
||||
try!(write!(self.writer,
|
||||
"\n{}{}\n\n",
|
||||
TAB,
|
||||
parser.create_usage_no_title(&[])));
|
||||
|
||||
|
@ -628,7 +637,8 @@ fn copy_and_capture<R: Read, W: Write>(r: &mut R,
|
|||
// The end of the reader was reached without finding the opening tag.
|
||||
// (either with or without having copied data to the writer)
|
||||
// Return None indicating that we are done.
|
||||
ReaderEmpty | DelimiterNotFound(_) => None,
|
||||
ReaderEmpty |
|
||||
DelimiterNotFound(_) => None,
|
||||
|
||||
// Something went wrong.
|
||||
ReadError(e) | WriteError(e) => Some(Err(e)),
|
||||
|
@ -792,7 +802,9 @@ fn find_idx_of_space(full: &str, mut start: usize) -> usize {
|
|||
let haystack = if full._is_char_boundary(start) {
|
||||
&full[..start]
|
||||
} else {
|
||||
while !full._is_char_boundary(start) { start -= 1; }
|
||||
while !full._is_char_boundary(start) {
|
||||
start -= 1;
|
||||
}
|
||||
&full[..start]
|
||||
};
|
||||
debugln!("haystack: {}", haystack);
|
||||
|
|
|
@ -108,3 +108,35 @@ macro_rules! validate_multiples {
|
|||
}
|
||||
};
|
||||
}
|
||||
|
||||
macro_rules! parse_positional {
|
||||
(
|
||||
$_self:ident,
|
||||
$p:ident,
|
||||
$arg_os:ident,
|
||||
$pos_only:ident,
|
||||
$pos_counter:ident,
|
||||
$matcher:ident
|
||||
) => {
|
||||
debugln!("macro=parse_positional!;");
|
||||
validate_multiples!($_self, $p, $matcher);
|
||||
|
||||
if let Err(e) = $_self.add_val_to_arg($p, &$arg_os, $matcher) {
|
||||
return Err(e);
|
||||
}
|
||||
if !$pos_only &&
|
||||
($_self.settings.is_set(AppSettings::TrailingVarArg) &&
|
||||
$pos_counter == $_self.positionals.len()) {
|
||||
$pos_only = true;
|
||||
}
|
||||
|
||||
$matcher.inc_occurrence_of($p.name);
|
||||
let _ = $_self.groups_for_arg($p.name)
|
||||
.and_then(|vec| Some($matcher.inc_occurrences_of(&*vec)));
|
||||
arg_post_processing!($_self, $p, $matcher);
|
||||
// Only increment the positional counter if it doesn't allow multiples
|
||||
if !$p.settings.is_set(ArgSettings::Multiple) {
|
||||
$pos_counter += 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ pub struct AppMeta<'b> {
|
|||
pub usage: Option<String>,
|
||||
pub help_str: Option<&'b str>,
|
||||
pub disp_ord: usize,
|
||||
pub template: Option<&'b str>,
|
||||
pub template: Option<&'b str>,
|
||||
}
|
||||
|
||||
impl<'b> Default for AppMeta<'b> {
|
||||
|
@ -35,12 +35,11 @@ impl<'b> Default for AppMeta<'b> {
|
|||
}
|
||||
|
||||
impl<'b> AppMeta<'b> {
|
||||
pub fn new() -> Self { Default::default() }
|
||||
pub fn new() -> Self {
|
||||
Default::default()
|
||||
}
|
||||
pub fn with_name(s: String) -> Self {
|
||||
AppMeta {
|
||||
name: s,
|
||||
..Default::default()
|
||||
}
|
||||
AppMeta { name: s, ..Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
108
src/app/mod.rs
108
src/app/mod.rs
|
@ -22,7 +22,7 @@ use std::fmt;
|
|||
use yaml_rust::Yaml;
|
||||
use vec_map::VecMap;
|
||||
|
||||
use args::{Arg, ArgSettings, AnyArg, ArgGroup, ArgMatches, ArgMatcher};
|
||||
use args::{AnyArg, Arg, ArgGroup, ArgMatcher, ArgMatches, ArgSettings};
|
||||
use app::parser::Parser;
|
||||
use app::help::Help;
|
||||
use errors::Error;
|
||||
|
@ -56,9 +56,11 @@ use errors::Result as ClapResult;
|
|||
/// // Your program logic starts here...
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct App<'a, 'b> where 'a: 'b {
|
||||
pub struct App<'a, 'b>
|
||||
where 'a: 'b
|
||||
{
|
||||
#[doc(hidden)]
|
||||
pub p: Parser<'a, 'b>
|
||||
pub p: Parser<'a, 'b>,
|
||||
}
|
||||
|
||||
|
||||
|
@ -74,7 +76,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
/// let prog = App::new("My Program")
|
||||
/// # ;
|
||||
/// ```
|
||||
pub fn new<S: Into<String>>(n: S) -> Self { App { p: Parser::with_name(n.into()) } }
|
||||
pub fn new<S: Into<String>>(n: S) -> Self {
|
||||
App { p: Parser::with_name(n.into()) }
|
||||
}
|
||||
|
||||
/// Creates a new instace of `App` from a .yml (YAML) file. A full example of supported YAML
|
||||
/// objects can be found in `examples/17_yaml.rs` and `examples/17_yaml.yml`. One great use for
|
||||
|
@ -112,15 +116,15 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
App::from(yaml)
|
||||
}
|
||||
|
||||
/// Sets a string of author(s) that will be displayed to the user when they
|
||||
/// Sets a string of author(s) that will be displayed to the user when they
|
||||
/// request the help information with `--help` or `-h`.
|
||||
///
|
||||
/// **Pro-tip:** If you turn on unstable features you can use `clap`s
|
||||
/// **Pro-tip:** If you turn on unstable features you can use `clap`s
|
||||
/// convienience macro `crate_authors!` to automatically set your
|
||||
/// application's author to the same thing as your crate at compile time.
|
||||
/// application's author to the same thing as your crate at compile time.
|
||||
/// See the `examples/`
|
||||
/// directory for more information
|
||||
///
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```no_run
|
||||
|
@ -492,7 +496,9 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
pub fn args_from_usage(mut self, usage: &'a str) -> Self {
|
||||
for line in usage.lines() {
|
||||
let l = line.trim();
|
||||
if l.is_empty() { continue; }
|
||||
if l.is_empty() {
|
||||
continue;
|
||||
}
|
||||
self.p.add_arg(&Arg::from_usage(l));
|
||||
}
|
||||
self
|
||||
|
@ -500,8 +506,8 @@ impl<'a, 'b> App<'a, 'b> {
|
|||
|
||||
/// Adds an `ArgGroup` to the application. `ArgGroup`s are a family of related arguments. By
|
||||
/// placing them in a logical group, you can build easier requirement and exclusion rules. For
|
||||
/// instance, you can make an entire `ArgGroup` required, meaning that one (and *only* one) argument
|
||||
/// from that group must be present at runtime.
|
||||
/// instance, you can make an entire `ArgGroup` required, meaning that one (and *only* one)
|
||||
/// argument from that group must be present at runtime.
|
||||
///
|
||||
/// You can also do things such as name an `ArgGroup` as a conflict to another argument.
|
||||
/// Meaning any of the arguments that belong to that group will cause a failure if present with
|
||||
|
@ -940,9 +946,7 @@ impl<'a> From<&'a Yaml> for App<'a, 'a> {
|
|||
|
||||
impl<'a, 'b> Clone for App<'a, 'b> {
|
||||
fn clone(&self) -> Self {
|
||||
App {
|
||||
p: self.p.clone(),
|
||||
}
|
||||
App { p: self.p.clone() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -950,28 +954,66 @@ impl<'n, 'e> AnyArg<'n, 'e> for App<'n, 'e> {
|
|||
fn name(&self) -> &'n str {
|
||||
unreachable!("App struct does not support AnyArg::name, this is a bug!")
|
||||
}
|
||||
fn overrides(&self) -> Option<&[&'e str]> { None }
|
||||
fn requires(&self) -> Option<&[&'e str]> { None }
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { None }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { None }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { None }
|
||||
fn is_set(&self, _: ArgSettings) -> bool { false }
|
||||
fn overrides(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn requires(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn required_unless(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> {
|
||||
None
|
||||
}
|
||||
fn is_set(&self, _: ArgSettings) -> bool {
|
||||
false
|
||||
}
|
||||
fn set(&mut self, _: ArgSettings) {
|
||||
unreachable!("App struct does not support AnyArg::set, this is a bug!")
|
||||
}
|
||||
fn has_switch(&self) -> bool { false }
|
||||
fn max_vals(&self) -> Option<u64> { None }
|
||||
fn num_vals(&self) -> Option<u64> { None }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { None }
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
|
||||
fn min_vals(&self) -> Option<u64> { None }
|
||||
fn short(&self) -> Option<char> { None }
|
||||
fn long(&self) -> Option<&'e str> { None }
|
||||
fn val_delim(&self) -> Option<char> { None }
|
||||
fn takes_value(&self) -> bool { true }
|
||||
fn help(&self) -> Option<&'e str> { self.p.meta.about }
|
||||
fn default_val(&self) -> Option<&'n str> { None }
|
||||
fn longest_filter(&self) -> bool { true }
|
||||
fn has_switch(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn max_vals(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn num_vals(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
|
||||
None
|
||||
}
|
||||
fn min_vals(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn short(&self) -> Option<char> {
|
||||
None
|
||||
}
|
||||
fn long(&self) -> Option<&'e str> {
|
||||
None
|
||||
}
|
||||
fn val_delim(&self) -> Option<char> {
|
||||
None
|
||||
}
|
||||
fn takes_value(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn help(&self) -> Option<&'e str> {
|
||||
self.p.meta.about
|
||||
}
|
||||
fn default_val(&self) -> Option<&'n str> {
|
||||
None
|
||||
}
|
||||
fn longest_filter(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> fmt::Display for App<'n, 'e> {
|
||||
|
|
|
@ -10,11 +10,11 @@ use vec_map::{self, VecMap};
|
|||
|
||||
use app::help::Help;
|
||||
use app::App;
|
||||
use args::{Arg, FlagBuilder, OptBuilder, ArgGroup, PosBuilder};
|
||||
use app::settings::{AppSettings, AppFlags};
|
||||
use args::{Arg, ArgGroup, FlagBuilder, OptBuilder, PosBuilder};
|
||||
use app::settings::{AppFlags, AppSettings};
|
||||
use args::{AnyArg, ArgMatcher};
|
||||
use args::settings::ArgSettings;
|
||||
use errors::{ErrorKind, Error};
|
||||
use errors::{Error, ErrorKind};
|
||||
use errors::Result as ClapResult;
|
||||
use INVALID_UTF8;
|
||||
use suggestions;
|
||||
|
@ -27,7 +27,9 @@ use args::MatchedArg;
|
|||
|
||||
#[allow(missing_debug_implementations)]
|
||||
#[doc(hidden)]
|
||||
pub struct Parser<'a, 'b> where 'a: 'b {
|
||||
pub struct Parser<'a, 'b>
|
||||
where 'a: 'b
|
||||
{
|
||||
required: Vec<&'b str>,
|
||||
short_list: Vec<char>,
|
||||
long_list: Vec<&'b str>,
|
||||
|
@ -72,32 +74,9 @@ impl<'a, 'b> Default for Parser<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
macro_rules! parse_positional {
|
||||
($_self:ident, $p:ident, $arg_os:ident, $pos_only:ident, $pos_counter:ident, $matcher:ident) => {
|
||||
debugln!("macro=parse_positional!;");
|
||||
validate_multiples!($_self, $p, $matcher);
|
||||
|
||||
if let Err(e) = $_self.add_val_to_arg($p, &$arg_os, $matcher) {
|
||||
return Err(e);
|
||||
}
|
||||
if !$pos_only &&
|
||||
($_self.settings.is_set(AppSettings::TrailingVarArg) &&
|
||||
$pos_counter == $_self.positionals.len()) {
|
||||
$pos_only = true;
|
||||
}
|
||||
|
||||
$matcher.inc_occurrence_of($p.name);
|
||||
let _ = $_self.groups_for_arg($p.name).and_then(|vec| Some($matcher.inc_occurrences_of(&*vec)));
|
||||
arg_post_processing!($_self, $p, $matcher);
|
||||
// Only increment the positional counter if it doesn't allow multiples
|
||||
if !$p.settings.is_set(ArgSettings::Multiple) {
|
||||
$pos_counter += 1;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
||||
impl<'a, 'b> Parser<'a, 'b>
|
||||
where 'a: 'b
|
||||
{
|
||||
pub fn with_name(n: String) -> Self {
|
||||
Parser { meta: AppMeta::with_name(n), ..Default::default() }
|
||||
}
|
||||
|
@ -116,22 +95,24 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
|
||||
// actually adds the arguments
|
||||
pub fn add_arg(&mut self, a: &Arg<'a, 'b>) {
|
||||
debug_assert!(!(self.flags.iter().any(|f| &f.name == &a.name)
|
||||
|| self.opts.iter().any(|o| o.name == a.name)
|
||||
|| self.positionals.values().any(|p| p.name == a.name)),
|
||||
format!("Non-unique argument name: {} is already in use", a.name));
|
||||
debug_assert!(!(self.flags.iter().any(|f| &f.name == &a.name) ||
|
||||
self.opts.iter().any(|o| o.name == a.name) ||
|
||||
self.positionals.values().any(|p| p.name == a.name)),
|
||||
format!("Non-unique argument name: {} is already in use", a.name));
|
||||
if let Some(grp) = a.group {
|
||||
let ag = self.groups.entry(grp).or_insert_with(|| ArgGroup::with_name(grp));
|
||||
ag.args.push(a.name);
|
||||
}
|
||||
if let Some(s) = a.short {
|
||||
debug_assert!(!self.short_list.contains(&s),
|
||||
format!("Argument short must be unique\n\n\t-{} is already in use", s));
|
||||
format!("Argument short must be unique\n\n\t-{} is already in use",
|
||||
s));
|
||||
self.short_list.push(s);
|
||||
}
|
||||
if let Some(l) = a.long {
|
||||
debug_assert!(!self.long_list.contains(&l),
|
||||
format!("Argument long must be unique\n\n\t--{} is already in use", l));
|
||||
format!("Argument long must be unique\n\n\t--{} is already in use",
|
||||
l));
|
||||
self.long_list.push(l);
|
||||
if l == "help" {
|
||||
self.set(AppSettings::NeedsLongHelp);
|
||||
|
@ -149,9 +130,10 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
a.index.unwrap() as usize
|
||||
};
|
||||
debug_assert!(!self.positionals.contains_key(i),
|
||||
format!("Argument \"{}\" has the same index as another positional \
|
||||
format!("Argument \"{}\" has the same index as another positional \
|
||||
argument\n\n\tPerhaps try .multiple(true) to allow one positional argument \
|
||||
to take multiple values", a.name));
|
||||
to take multiple values",
|
||||
a.name));
|
||||
let pb = PosBuilder::from_arg(&a, i as u64, &mut self.required);
|
||||
self.positionals.insert(i, pb);
|
||||
} else if a.is_set(ArgSettings::TakesValue) {
|
||||
|
@ -177,8 +159,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
if a.is_set(ArgSettings::Global) {
|
||||
debug_assert!(!a.is_set(ArgSettings::Required),
|
||||
format!("Global arguments cannot be required.\n\n\t'{}' is marked as global and \
|
||||
required", a.name));
|
||||
format!("Global arguments cannot be required.\n\n\t'{}' is marked as \
|
||||
global and required",
|
||||
a.name));
|
||||
self.global_args.push(a.into());
|
||||
}
|
||||
}
|
||||
|
@ -212,19 +195,25 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
if subcmd.p.meta.name == "help" {
|
||||
sdebugln!("Yes");
|
||||
self.settings.set(AppSettings::NeedsSubcommandHelp);
|
||||
} else { sdebugln!("No"); }
|
||||
} else {
|
||||
sdebugln!("No");
|
||||
}
|
||||
debug!("Using Setting VersionlessSubcommands...");
|
||||
if self.settings.is_set(AppSettings::VersionlessSubcommands) {
|
||||
sdebugln!("Yes");
|
||||
subcmd.p.settings.set(AppSettings::DisableVersion);
|
||||
} else { sdebugln!("No"); }
|
||||
} else {
|
||||
sdebugln!("No");
|
||||
}
|
||||
debug!("Using Setting GlobalVersion...");
|
||||
if self.settings.is_set(AppSettings::GlobalVersion) && subcmd.p.meta.version.is_none() &&
|
||||
self.meta.version.is_some() {
|
||||
sdebugln!("Yes");
|
||||
subcmd = subcmd.setting(AppSettings::GlobalVersion)
|
||||
.version(self.meta.version.unwrap());
|
||||
} else { sdebugln!("No"); }
|
||||
} else {
|
||||
sdebugln!("No");
|
||||
}
|
||||
if self.settings.is_set(AppSettings::DeriveDisplayOrder) {
|
||||
subcmd.p.meta.disp_ord = self.subcommands.len();
|
||||
}
|
||||
|
@ -237,9 +226,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
|
||||
#[cfg_attr(feature = "lints", allow(for_kv_map))]
|
||||
pub fn get_required_from(&self,
|
||||
reqs: &[&'a str],
|
||||
matcher: Option<&ArgMatcher<'a>>)
|
||||
-> VecDeque<String> {
|
||||
reqs: &[&'a str],
|
||||
matcher: Option<&ArgMatcher<'a>>)
|
||||
-> VecDeque<String> {
|
||||
let mut c_flags: Vec<&str> = vec![];
|
||||
let mut c_pos: Vec<&str> = vec![];
|
||||
let mut c_opt: Vec<&str> = vec![];
|
||||
|
@ -373,16 +362,19 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
// positional arguments to verify there are no gaps (i.e. supplying an index of 1 and 3
|
||||
// but no 2)
|
||||
if let Some((idx, ref p)) = self.positionals.iter().rev().next() {
|
||||
assert!(!(idx != self.positionals.len()),
|
||||
format!("Found positional argument \"{}\" who's index is {} but there are only {} \
|
||||
positional arguments defined", p.name, idx, self.positionals.len()));
|
||||
debug_assert!(!(idx != self.positionals.len()),
|
||||
format!("Found positional argument \"{}\" who's index is {} but there are \
|
||||
only {} positional arguments defined",
|
||||
p.name,
|
||||
idx,
|
||||
self.positionals.len()));
|
||||
}
|
||||
|
||||
// Next we verify that only the highest index has a .multiple(true) (if any)
|
||||
assert!(!self.positionals.values()
|
||||
.any(|a|
|
||||
a.settings.is_set(ArgSettings::Multiple) &&
|
||||
(a.index as usize != self.positionals.len())
|
||||
debug_assert!(!self.positionals
|
||||
.values()
|
||||
.any(|a| a.settings.is_set(ArgSettings::Multiple) &&
|
||||
(a.index as usize != self.positionals.len())
|
||||
),
|
||||
"Only the positional argument with the highest index may accept multiple values");
|
||||
|
||||
|
@ -392,10 +384,10 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
for p in self.positionals.values().rev() {
|
||||
if found {
|
||||
debug_assert!(p.settings.is_set(ArgSettings::Required),
|
||||
"Found positional argument which is not required with a lower index than a \
|
||||
required positional argument: {:?} index {}",
|
||||
p.name,
|
||||
p.index);
|
||||
"Found positional argument which is not required with a lower index \
|
||||
than a required positional argument: {:?} index {}",
|
||||
p.name,
|
||||
p.index);
|
||||
} else if p.settings.is_set(ArgSettings::Required) {
|
||||
found = true;
|
||||
continue;
|
||||
|
@ -419,9 +411,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
// The actual parsing function
|
||||
#[cfg_attr(feature = "lints", allow(while_let_on_iterator))]
|
||||
pub fn get_matches_with<I, T>(&mut self,
|
||||
matcher: &mut ArgMatcher<'a>,
|
||||
it: &mut I)
|
||||
-> ClapResult<()>
|
||||
matcher: &mut ArgMatcher<'a>,
|
||||
it: &mut I)
|
||||
-> ClapResult<()>
|
||||
where I: Iterator<Item = T>,
|
||||
T: Into<OsString>
|
||||
{
|
||||
|
@ -464,8 +456,8 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
if arg_os.starts_with(b"--") {
|
||||
if arg_os.len_() == 2 {
|
||||
// The user has passed '--' which means only positional args follow no matter
|
||||
// what they start with
|
||||
// The user has passed '--' which means only positional args follow no
|
||||
// matter what they start with
|
||||
pos_only = true;
|
||||
continue;
|
||||
}
|
||||
|
@ -486,7 +478,11 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
let mut sc = {
|
||||
let mut sc: &Parser = self;
|
||||
for (i, cmd) in cmds.iter().enumerate() {
|
||||
if let Some(c) = sc.subcommands.iter().filter(|s| &*s.p.meta.name == cmd).next().map(|sc| &sc.p) {
|
||||
if let Some(c) = sc.subcommands
|
||||
.iter()
|
||||
.filter(|s| &*s.p.meta.name == cmd)
|
||||
.next()
|
||||
.map(|sc| &sc.p) {
|
||||
sc = c;
|
||||
if i == cmds.len() - 1 {
|
||||
break;
|
||||
|
@ -495,7 +491,10 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
return Err(
|
||||
Error::unrecognized_subcommand(
|
||||
cmd.to_string_lossy().into_owned(),
|
||||
self.meta.bin_name.as_ref().unwrap_or(&self.meta.name)));
|
||||
self.meta
|
||||
.bin_name
|
||||
.as_ref()
|
||||
.unwrap_or(&self.meta.name)));
|
||||
}
|
||||
}
|
||||
sc.clone()
|
||||
|
@ -505,14 +504,17 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
subcmd_name = Some(arg_os.to_str().expect(INVALID_UTF8).to_owned());
|
||||
break;
|
||||
} else if let Some(candidate) = suggestions::did_you_mean(
|
||||
&*arg_os.to_string_lossy(),
|
||||
self.subcommands.iter().map(|s| &s.p.meta.name)) {
|
||||
return Err(
|
||||
Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
|
||||
candidate,
|
||||
self.meta.bin_name.as_ref().unwrap_or(&self.meta.name),
|
||||
&*self.create_current_usage(matcher)));
|
||||
} else if let Some(cdate) = suggestions::did_you_mean(&*arg_os.to_string_lossy(),
|
||||
self.subcommands
|
||||
.iter()
|
||||
.map(|s| &s.p.meta.name)) {
|
||||
return Err(Error::invalid_subcommand(arg_os.to_string_lossy().into_owned(),
|
||||
cdate,
|
||||
self.meta
|
||||
.bin_name
|
||||
.as_ref()
|
||||
.unwrap_or(&self.meta.name),
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -524,7 +526,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
while let Some(v) = it.next() {
|
||||
let a = v.into();
|
||||
if let None = a.to_str() {
|
||||
if !self.settings.is_set(AppSettings::StrictUtf8) {
|
||||
if !self.settings.is_set(AppSettings::StrictUtf8) {
|
||||
return Err(
|
||||
Error::invalid_utf8(&*self.create_current_usage(matcher))
|
||||
);
|
||||
|
@ -538,10 +540,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
matches: sc_m.into(),
|
||||
});
|
||||
} else {
|
||||
return Err(Error::unknown_argument(
|
||||
&*arg_os.to_string_lossy(),
|
||||
"",
|
||||
&*self.create_current_usage(matcher)));
|
||||
return Err(Error::unknown_argument(&*arg_os.to_string_lossy(),
|
||||
"",
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -561,11 +562,11 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
} else {
|
||||
return Err(Error::empty_value(self.positionals
|
||||
.values()
|
||||
.filter(|p| &p.name == &a)
|
||||
.next()
|
||||
.expect(INTERNAL_ERROR_MSG),
|
||||
&*self.create_current_usage(matcher)));
|
||||
.values()
|
||||
.filter(|p| &p.name == &a)
|
||||
.next()
|
||||
.expect(INTERNAL_ERROR_MSG),
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -575,7 +576,7 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
matcher.usage(self.create_usage(&[]));
|
||||
|
||||
if !(self.settings.is_set(AppSettings::SubcommandsNegateReqs) && subcmd_name.is_some()) &&
|
||||
!reqs_validated {
|
||||
!reqs_validated {
|
||||
try!(self.validate_required(matcher));
|
||||
}
|
||||
if let Some(sc_name) = subcmd_name {
|
||||
|
@ -605,7 +606,11 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn parse_subcommand<I, T>(&mut self, sc_name: String, matcher: &mut ArgMatcher<'a>, it: &mut I) -> ClapResult<()>
|
||||
fn parse_subcommand<I, T>(&mut self,
|
||||
sc_name: String,
|
||||
matcher: &mut ArgMatcher<'a>,
|
||||
it: &mut I)
|
||||
-> ClapResult<()>
|
||||
where I: Iterator<Item = T>,
|
||||
T: Into<OsString>
|
||||
{
|
||||
|
@ -632,21 +637,24 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
// bin_name should be parent's bin_name + [<reqs>] + the sc's name separated by
|
||||
// a space
|
||||
sc.p.meta.usage = Some(format!("{}{}{}",
|
||||
self.meta.bin_name.as_ref().unwrap_or(&String::new()),
|
||||
if self.meta.bin_name.is_some() {
|
||||
&*mid_string
|
||||
} else {
|
||||
""
|
||||
},
|
||||
&*sc.p.meta.name));
|
||||
self.meta.bin_name.as_ref().unwrap_or(&String::new()),
|
||||
if self.meta.bin_name.is_some() {
|
||||
&*mid_string
|
||||
} else {
|
||||
""
|
||||
},
|
||||
&*sc.p.meta.name));
|
||||
sc.p.meta.bin_name = Some(format!("{}{}{}",
|
||||
self.meta.bin_name.as_ref().unwrap_or(&String::new()),
|
||||
if self.meta.bin_name.is_some() {
|
||||
" "
|
||||
} else {
|
||||
""
|
||||
},
|
||||
&*sc.p.meta.name));
|
||||
self.meta
|
||||
.bin_name
|
||||
.as_ref()
|
||||
.unwrap_or(&String::new()),
|
||||
if self.meta.bin_name.is_some() {
|
||||
" "
|
||||
} else {
|
||||
""
|
||||
},
|
||||
&*sc.p.meta.name));
|
||||
try!(sc.p.get_matches_with(&mut sc_matcher, it));
|
||||
matcher.subcommand(SubCommand {
|
||||
name: sc.p.meta.name.clone(),
|
||||
|
@ -746,9 +754,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
} else if self.groups.contains_key(&**n) {
|
||||
g_vec.push(*n);
|
||||
} else if let Some(p) = self.positionals
|
||||
.values()
|
||||
.filter(|p| &p.name == n)
|
||||
.next() {
|
||||
.values()
|
||||
.filter(|p| &p.name == n)
|
||||
.next() {
|
||||
args.push(p.to_string());
|
||||
}
|
||||
}
|
||||
|
@ -819,36 +827,39 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
.iter()
|
||||
.any(|s| &s.p.meta.name[..] == "help") {
|
||||
debugln!("Building help");
|
||||
self.subcommands.push(App::new("help").about("Prints this message or the help of the given subcommand(s)"));
|
||||
self.subcommands
|
||||
.push(App::new("help")
|
||||
.about("Prints this message or the help of the given subcommand(s)"));
|
||||
}
|
||||
}
|
||||
|
||||
// Retrieves the names of all args the user has supplied thus far, except required ones
|
||||
// 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()
|
||||
.filter(|&o| &&o.name == n)
|
||||
.next() {
|
||||
!o.settings.is_set(ArgSettings::Required)
|
||||
} else if let Some(p) = self.positionals
|
||||
.values()
|
||||
.filter(|&p| &&p.name == n)
|
||||
.next() {
|
||||
!p.settings.is_set(ArgSettings::Required)
|
||||
} else {
|
||||
true // flags can't be required, so they're always true
|
||||
}})
|
||||
.map(|&n| n)
|
||||
.collect::<Vec<_>>())
|
||||
self.create_usage(&*matcher.arg_names()
|
||||
.iter()
|
||||
.filter(|n| {
|
||||
if let Some(o) = self.opts
|
||||
.iter()
|
||||
.filter(|&o| &&o.name == n)
|
||||
.next() {
|
||||
!o.settings.is_set(ArgSettings::Required)
|
||||
} else if let Some(p) = self.positionals
|
||||
.values()
|
||||
.filter(|&p| &&p.name == n)
|
||||
.next() {
|
||||
!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<()> {
|
||||
debug!("Checking if --{} is help or version...", arg.to_str().unwrap());
|
||||
debug!("Checking if --{} is help or version...",
|
||||
arg.to_str().unwrap());
|
||||
if arg == "help" && self.settings.is_set(AppSettings::NeedsLongHelp) {
|
||||
sdebugln!("Help");
|
||||
try!(self._help());
|
||||
|
@ -866,11 +877,15 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
debug!("Checking if -{} is help or version...", arg);
|
||||
if let Some(h) = self.help_short {
|
||||
sdebugln!("Help");
|
||||
if arg == h { try!(self._help()); }
|
||||
if arg == h {
|
||||
try!(self._help());
|
||||
}
|
||||
}
|
||||
if let Some(v) = self.version_short {
|
||||
sdebugln!("Help");
|
||||
if arg == v { try!(self._version()); }
|
||||
if arg == v {
|
||||
try!(self._version());
|
||||
}
|
||||
}
|
||||
sdebugln!("Neither");
|
||||
Ok(())
|
||||
|
@ -899,7 +914,8 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
fn parse_long_arg(&mut self,
|
||||
matcher: &mut ArgMatcher<'a>,
|
||||
full_arg: &OsStr)
|
||||
-> ClapResult<Option<&'b str>> { // maybe here lifetime should be 'a
|
||||
-> ClapResult<Option<&'b str>> {
|
||||
// maybe here lifetime should be 'a
|
||||
debugln!("fn=parse_long_arg;");
|
||||
let mut val = None;
|
||||
debug!("Does it contain '='...");
|
||||
|
@ -914,18 +930,18 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
};
|
||||
|
||||
if let Some(opt) = self.opts
|
||||
.iter()
|
||||
.filter(|v| v.long.is_some() && &*v.long.unwrap() == arg)
|
||||
.next() {
|
||||
.iter()
|
||||
.filter(|v| v.long.is_some() && &*v.long.unwrap() == arg)
|
||||
.next() {
|
||||
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()
|
||||
.filter(|v| v.long.is_some() && &*v.long.unwrap() == arg)
|
||||
.next() {
|
||||
.iter()
|
||||
.filter(|v| v.long.is_some() && &*v.long.unwrap() == arg)
|
||||
.next() {
|
||||
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
|
||||
|
@ -958,17 +974,22 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
// Option: -o
|
||||
// Value: val
|
||||
if let Some(opt) = self.opts
|
||||
.iter()
|
||||
.filter(|&v| v.short.is_some() && v.short.unwrap() == c)
|
||||
.next() {
|
||||
.iter()
|
||||
.filter(|&v| v.short.is_some() && v.short.unwrap() == c)
|
||||
.next() {
|
||||
debugln!("Found valid short opt -{} in '{}'", c, arg);
|
||||
// Check for trailing concatenated value
|
||||
let p: Vec<_> = arg.splitn(2, c).collect();
|
||||
debugln!("arg: {:?}, arg_os: {:?}, full_arg: {:?}", arg, arg_os, full_arg);
|
||||
debugln!("arg: {:?}, arg_os: {:?}, full_arg: {:?}",
|
||||
arg,
|
||||
arg_os,
|
||||
full_arg);
|
||||
debugln!("p[0]: {:?}, p[1]: {:?}", p[0].as_bytes(), p[1].as_bytes());
|
||||
let i = p[0].as_bytes().len() + 1;
|
||||
let val = if p[1].as_bytes().len() > 0 {
|
||||
debugln!("setting val: {:?} (bytes), {:?} (ascii)", arg_os.split_at(i).1.as_bytes(), arg_os.split_at(i).1);
|
||||
debugln!("setting val: {:?} (bytes), {:?} (ascii)",
|
||||
arg_os.split_at(i).1.as_bytes(),
|
||||
arg_os.split_at(i).1);
|
||||
Some(arg_os.split_at(i).1)
|
||||
} else {
|
||||
None
|
||||
|
@ -980,7 +1001,10 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
arg_post_processing!(self, opt, matcher);
|
||||
|
||||
return Ok(ret);
|
||||
} else if let Some(flag) = self.flags.iter().filter(|&v| v.short.is_some() && v.short.unwrap() == c).next() {
|
||||
} else if let Some(flag) = self.flags
|
||||
.iter()
|
||||
.filter(|&v| v.short.is_some() && v.short.unwrap() == c)
|
||||
.next() {
|
||||
debugln!("Found valid short flag -{}", c);
|
||||
// Only flags can be help or version
|
||||
try!(self.check_for_help_and_version_char(c));
|
||||
|
@ -992,8 +1016,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
let mut arg = String::new();
|
||||
arg.push('-');
|
||||
arg.push(c);
|
||||
return Err(
|
||||
Error::unknown_argument(&*arg, "", &*self.create_current_usage(matcher)));
|
||||
return Err(Error::unknown_argument(&*arg,
|
||||
"",
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
Ok(None)
|
||||
|
@ -1016,7 +1041,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
sdebugln!("Found - {:?}, len: {}", v, v.len_());
|
||||
try!(self.add_val_to_arg(opt, v, matcher));
|
||||
} else { sdebugln!("None"); }
|
||||
} else {
|
||||
sdebugln!("None");
|
||||
}
|
||||
|
||||
matcher.inc_occurrence_of(opt.name);
|
||||
// Increment or create the group "args"
|
||||
|
@ -1029,11 +1056,12 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
|
||||
fn add_val_to_arg<A>(&self,
|
||||
arg: &A,
|
||||
val: &OsStr,
|
||||
matcher: &mut ArgMatcher<'a>)
|
||||
-> ClapResult<Option<&'a str>>
|
||||
where A: AnyArg<'a, 'b> + Display {
|
||||
arg: &A,
|
||||
val: &OsStr,
|
||||
matcher: &mut ArgMatcher<'a>)
|
||||
-> ClapResult<Option<&'a str>>
|
||||
where A: AnyArg<'a, 'b> + Display
|
||||
{
|
||||
debugln!("fn=add_val_to_arg;");
|
||||
let mut ret = None;
|
||||
if let Some(delim) = arg.val_delim() {
|
||||
|
@ -1050,7 +1078,11 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
Ok(ret)
|
||||
}
|
||||
|
||||
fn add_single_val_to_arg<A>(&self, arg: &A, v: &OsStr, matcher: &mut ArgMatcher<'a>) -> ClapResult<Option<&'a str>>
|
||||
fn add_single_val_to_arg<A>(&self,
|
||||
arg: &A,
|
||||
v: &OsStr,
|
||||
matcher: &mut ArgMatcher<'a>)
|
||||
-> ClapResult<Option<&'a str>>
|
||||
where A: AnyArg<'a, 'b> + Display
|
||||
{
|
||||
debugln!("adding val: {:?}", v);
|
||||
|
@ -1068,8 +1100,13 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
self.validate_value(arg, v, matcher)
|
||||
}
|
||||
|
||||
fn validate_value<A>(&self, arg: &A, val: &OsStr, matcher: &ArgMatcher<'a>) -> ClapResult<Option<&'a str>>
|
||||
where A: AnyArg<'a, 'b> + Display {
|
||||
fn validate_value<A>(&self,
|
||||
arg: &A,
|
||||
val: &OsStr,
|
||||
matcher: &ArgMatcher<'a>)
|
||||
-> ClapResult<Option<&'a str>>
|
||||
where A: AnyArg<'a, 'b> + Display
|
||||
{
|
||||
debugln!("fn=validate_value; val={:?}", val);
|
||||
if self.is_set(AppSettings::StrictUtf8) && val.to_str().is_none() {
|
||||
return Err(Error::invalid_utf8(&*self.create_current_usage(matcher)));
|
||||
|
@ -1077,16 +1114,14 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
if let Some(ref p_vals) = arg.possible_vals() {
|
||||
let val_str = val.to_string_lossy();
|
||||
if !p_vals.contains(&&*val_str) {
|
||||
return Err(
|
||||
Error::invalid_value(val_str,
|
||||
p_vals,
|
||||
arg,
|
||||
&*self.create_current_usage(matcher)));
|
||||
return Err(Error::invalid_value(val_str,
|
||||
p_vals,
|
||||
arg,
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
if !arg.is_set(ArgSettings::EmptyValues) &&
|
||||
val.is_empty_() &&
|
||||
matcher.contains(&*arg.name()) {
|
||||
if !arg.is_set(ArgSettings::EmptyValues) && val.is_empty_() &&
|
||||
matcher.contains(&*arg.name()) {
|
||||
return Err(Error::empty_value(arg, &*self.create_current_usage(matcher)));
|
||||
}
|
||||
if let Some(ref vtor) = arg.validator() {
|
||||
|
@ -1100,7 +1135,10 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
Ok(None)
|
||||
}
|
||||
|
||||
fn parse_flag(&self, flag: &FlagBuilder<'a, 'b>, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
|
||||
fn parse_flag(&self,
|
||||
flag: &FlagBuilder<'a, 'b>,
|
||||
matcher: &mut ArgMatcher<'a>)
|
||||
-> ClapResult<()> {
|
||||
debugln!("fn=parse_flag;");
|
||||
validate_multiples!(self, flag, matcher);
|
||||
|
||||
|
@ -1166,14 +1204,14 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
continue;
|
||||
} else {
|
||||
if let Some(opt) = self.opts
|
||||
.iter()
|
||||
.filter(|o| &o.name == name)
|
||||
.next() {
|
||||
.iter()
|
||||
.filter(|o| &o.name == name)
|
||||
.next() {
|
||||
try!(self._validate_num_vals(opt, ma, matcher));
|
||||
} else if let Some(pos) = self.positionals
|
||||
.values()
|
||||
.filter(|p| &p.name == name)
|
||||
.next() {
|
||||
.values()
|
||||
.filter(|p| &p.name == name)
|
||||
.next() {
|
||||
try!(self._validate_num_vals(pos, ma, matcher));
|
||||
}
|
||||
}
|
||||
|
@ -1194,46 +1232,48 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
};
|
||||
if should_err {
|
||||
debugln!("Sending error WrongNumberOfValues");
|
||||
return Err(Error::wrong_number_of_values(
|
||||
a,
|
||||
num,
|
||||
if a.is_set(ArgSettings::Multiple) {
|
||||
(ma.vals.len() % num as usize)
|
||||
} else {
|
||||
ma.vals.len()
|
||||
},
|
||||
if ma.vals.len() == 1 ||
|
||||
(a.is_set(ArgSettings::Multiple) &&
|
||||
(ma.vals.len() % num as usize) == 1) {
|
||||
"as"
|
||||
} else {
|
||||
"ere"
|
||||
},
|
||||
&*self.create_current_usage(matcher)));
|
||||
return Err(Error::wrong_number_of_values(a,
|
||||
num,
|
||||
if a.is_set(ArgSettings::Multiple) {
|
||||
(ma.vals.len() % num as usize)
|
||||
} else {
|
||||
ma.vals.len()
|
||||
},
|
||||
if ma.vals.len() == 1 ||
|
||||
(a.is_set(ArgSettings::Multiple) &&
|
||||
(ma.vals.len() % num as usize) ==
|
||||
1) {
|
||||
"as"
|
||||
} else {
|
||||
"ere"
|
||||
},
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
if let Some(num) = a.max_vals() {
|
||||
debugln!("max_vals set: {}", num);
|
||||
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),
|
||||
a,
|
||||
&*self.create_current_usage(matcher)));
|
||||
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),
|
||||
a,
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
if let Some(num) = a.min_vals() {
|
||||
debugln!("min_vals set: {}", num);
|
||||
if (ma.vals.len() as u64) < num {
|
||||
debugln!("Sending error TooFewValues");
|
||||
return Err(Error::too_few_values(
|
||||
a,
|
||||
num,
|
||||
ma.vals.len(),
|
||||
&*self.create_current_usage(matcher)));
|
||||
return Err(Error::too_few_values(a,
|
||||
num,
|
||||
ma.vals.len(),
|
||||
&*self.create_current_usage(matcher)));
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -1246,20 +1286,29 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
if let Some(grp) = self.groups.get(name) {
|
||||
for arg in &grp.args {
|
||||
if matcher.contains(arg) { continue 'outer; }
|
||||
if matcher.contains(arg) {
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.groups.values().any(|g| g.args.contains(name)) {
|
||||
continue 'outer;
|
||||
}
|
||||
if let Some(a) = self.flags.iter().filter(|f| &f.name == name).next() {
|
||||
if self.is_missing_required_ok(a, matcher) { continue 'outer; }
|
||||
if self.is_missing_required_ok(a, matcher) {
|
||||
continue 'outer;
|
||||
}
|
||||
} else if let Some(a) = self.opts.iter().filter(|o| &o.name == name).next() {
|
||||
if self.is_missing_required_ok(a, matcher) { continue 'outer; }
|
||||
if self.is_missing_required_ok(a, matcher) {
|
||||
continue 'outer;
|
||||
}
|
||||
} else if let Some(a) = self.positionals.values().filter(|p| &p.name == name).next() {
|
||||
if self.is_missing_required_ok(a, matcher) { continue 'outer; }
|
||||
if self.is_missing_required_ok(a, matcher) {
|
||||
continue 'outer;
|
||||
}
|
||||
}
|
||||
let err = if self.settings.is_set(AppSettings::ArgRequiredElseHelp) && matcher.is_empty() {
|
||||
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<_>>();
|
||||
|
@ -1276,22 +1325,24 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn is_missing_required_ok<A>(&self, a: &A, matcher: &ArgMatcher) -> bool where A: AnyArg<'a, 'b> {
|
||||
fn is_missing_required_ok<A>(&self, a: &A, matcher: &ArgMatcher) -> bool
|
||||
where A: AnyArg<'a, 'b>
|
||||
{
|
||||
if let Some(bl) = a.blacklist() {
|
||||
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))) {
|
||||
if matcher.contains(n) ||
|
||||
self.groups
|
||||
.get(n)
|
||||
.map_or(false, |g| g.args.iter().any(|an| matcher.contains(an))) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} else if let Some(ru) = a.required_unless() {
|
||||
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 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;
|
||||
}
|
||||
|
@ -1306,23 +1357,26 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
|
||||
fn did_you_mean_error(&self, arg: &str, matcher: &mut ArgMatcher<'a>) -> ClapResult<()> {
|
||||
// Didn't match a flag or option...maybe it was a typo and close to one
|
||||
let suffix = suggestions::did_you_mean_suffix(arg,
|
||||
self.long_list.iter(),
|
||||
suggestions::DidYouMeanMessageStyle::LongFlag);
|
||||
let suffix =
|
||||
suggestions::did_you_mean_suffix(arg,
|
||||
self.long_list.iter(),
|
||||
suggestions::DidYouMeanMessageStyle::LongFlag);
|
||||
|
||||
// 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()
|
||||
.filter(|o| o.long.is_some() && o.long.unwrap() == name)
|
||||
.next() {
|
||||
self.groups_for_arg(&*opt.name).and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
|
||||
.iter()
|
||||
.filter(|o| o.long.is_some() && o.long.unwrap() == name)
|
||||
.next() {
|
||||
self.groups_for_arg(&*opt.name)
|
||||
.and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
|
||||
matcher.insert(&*opt.name);
|
||||
} else if let Some(flg) = self.flags
|
||||
.iter()
|
||||
.filter(|f| f.long.is_some() && f.long.unwrap() == name)
|
||||
.next() {
|
||||
self.groups_for_arg(&*flg.name).and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
|
||||
.iter()
|
||||
.filter(|f| f.long.is_some() && f.long.unwrap() == name)
|
||||
.next() {
|
||||
self.groups_for_arg(&*flg.name)
|
||||
.and_then(|grps| Some(matcher.inc_occurrences_of(&*grps)));
|
||||
matcher.insert(&*flg.name);
|
||||
}
|
||||
}
|
||||
|
@ -1352,9 +1406,11 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
if let Some(u) = self.meta.usage_str {
|
||||
usage.push_str(&*u);
|
||||
} else if used.is_empty() {
|
||||
usage.push_str(&*self.meta.usage
|
||||
usage.push_str(&*self.meta
|
||||
.usage
|
||||
.as_ref()
|
||||
.unwrap_or(self.meta.bin_name
|
||||
.unwrap_or(self.meta
|
||||
.bin_name
|
||||
.as_ref()
|
||||
.unwrap_or(&self.meta.name)));
|
||||
let mut reqs: Vec<&str> = self.required().map(|r| &**r).collect();
|
||||
|
@ -1368,9 +1424,8 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
} else {
|
||||
usage.push_str(" [OPTIONS]");
|
||||
}
|
||||
if !self.is_set(AppSettings::UnifiedHelpMessage)
|
||||
&& self.has_opts()
|
||||
&& self.opts.iter().any(|a| !a.settings.is_set(ArgSettings::Required)) {
|
||||
if !self.is_set(AppSettings::UnifiedHelpMessage) && self.has_opts() &&
|
||||
self.opts.iter().any(|a| !a.settings.is_set(ArgSettings::Required)) {
|
||||
usage.push_str(" [OPTIONS]");
|
||||
}
|
||||
|
||||
|
@ -1378,15 +1433,14 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
|
||||
// places a '--' in the usage string if there are args and options
|
||||
// supporting multiple values
|
||||
if self.has_positionals()
|
||||
&& self.opts.iter().any(|a| a.settings.is_set(ArgSettings::Multiple))
|
||||
// || self.positionals.values().any(|a| a.settings.is_set(ArgSettings::Multiple)))
|
||||
&& self.positionals.values().any(|a| !a.settings.is_set(ArgSettings::Required))
|
||||
&& !self.has_subcommands() {
|
||||
if self.has_positionals() &&
|
||||
self.opts.iter().any(|a| a.settings.is_set(ArgSettings::Multiple)) &&
|
||||
self.positionals.values().any(|a| !a.settings.is_set(ArgSettings::Required)) &&
|
||||
!self.has_subcommands() {
|
||||
usage.push_str(" [--]")
|
||||
}
|
||||
if self.has_positionals()
|
||||
&& self.positionals.values().any(|a| !a.settings.is_set(ArgSettings::Required)) {
|
||||
if self.has_positionals() &&
|
||||
self.positionals.values().any(|a| !a.settings.is_set(ArgSettings::Required)) {
|
||||
usage.push_str(" [ARGS]");
|
||||
}
|
||||
|
||||
|
@ -1412,11 +1466,17 @@ impl<'a, 'b> Parser<'a, 'b> where '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.push_str(&self.meta
|
||||
.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>");
|
||||
|
@ -1433,12 +1493,21 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
if let Some(bn) = self.meta.bin_name.as_ref() {
|
||||
if bn.contains(' ') {
|
||||
// Incase we're dealing with subcommands i.e. git mv is translated to git-mv
|
||||
writeln!(w, "{} {}", bn.replace(" ", "-"), self.meta.version.unwrap_or("".into()))
|
||||
writeln!(w,
|
||||
"{} {}",
|
||||
bn.replace(" ", "-"),
|
||||
self.meta.version.unwrap_or("".into()))
|
||||
} else {
|
||||
writeln!(w, "{} {}", &self.meta.name[..], self.meta.version.unwrap_or("".into()))
|
||||
writeln!(w,
|
||||
"{} {}",
|
||||
&self.meta.name[..],
|
||||
self.meta.version.unwrap_or("".into()))
|
||||
}
|
||||
} else {
|
||||
writeln!(w, "{} {}", &self.meta.name[..], self.meta.version.unwrap_or("".into()))
|
||||
writeln!(w,
|
||||
"{} {}",
|
||||
&self.meta.name[..],
|
||||
self.meta.version.unwrap_or("".into()))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1457,7 +1526,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
macro_rules! add_val {
|
||||
($_self:ident, $a:ident, $m:ident) => {
|
||||
if $m.get($a.name).is_none() {
|
||||
try!($_self.add_val_to_arg($a, OsStr::new($a.default_val.as_ref().unwrap()), $m));
|
||||
try!($_self.add_val_to_arg($a, OsStr::new($a.default_val
|
||||
.as_ref()
|
||||
.unwrap()), $m));
|
||||
arg_post_processing!($_self, $a, $m);
|
||||
}
|
||||
};
|
||||
|
@ -1484,7 +1555,9 @@ impl<'a, 'b> Parser<'a, 'b> where 'a: 'b {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b> Clone for Parser<'a, 'b> where 'a: 'b {
|
||||
impl<'a, 'b> Clone for Parser<'a, 'b>
|
||||
where 'a: 'b
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Parser {
|
||||
required: self.required.clone(),
|
||||
|
|
|
@ -509,23 +509,40 @@ mod test {
|
|||
|
||||
#[test]
|
||||
fn app_settings_fromstr() {
|
||||
assert_eq!("subcommandsnegatereqs".parse::<AppSettings>().unwrap(), AppSettings::SubcommandsNegateReqs);
|
||||
assert_eq!("subcommandsrequired".parse::<AppSettings>().unwrap(), AppSettings::SubcommandRequired);
|
||||
assert_eq!("argrequiredelsehelp".parse::<AppSettings>().unwrap(), AppSettings::ArgRequiredElseHelp);
|
||||
assert_eq!("globalversion".parse::<AppSettings>().unwrap(), AppSettings::GlobalVersion);
|
||||
assert_eq!("versionlesssubcommands".parse::<AppSettings>().unwrap(), AppSettings::VersionlessSubcommands);
|
||||
assert_eq!("unifiedhelpmessage".parse::<AppSettings>().unwrap(), AppSettings::UnifiedHelpMessage);
|
||||
assert_eq!("waitonerror".parse::<AppSettings>().unwrap(), AppSettings::WaitOnError);
|
||||
assert_eq!("subcommandrequiredelsehelp".parse::<AppSettings>().unwrap(), AppSettings::SubcommandRequiredElseHelp);
|
||||
assert_eq!("allowexternalsubcommands".parse::<AppSettings>().unwrap(), AppSettings::AllowExternalSubcommands);
|
||||
assert_eq!("trailingvararg".parse::<AppSettings>().unwrap(), AppSettings::TrailingVarArg);
|
||||
assert_eq!("nobinaryname".parse::<AppSettings>().unwrap(), AppSettings::NoBinaryName);
|
||||
assert_eq!("strictutf8".parse::<AppSettings>().unwrap(), AppSettings::StrictUtf8);
|
||||
assert_eq!("allowinvalidutf8".parse::<AppSettings>().unwrap(), AppSettings::AllowInvalidUtf8);
|
||||
assert_eq!("allowleadinghyphen".parse::<AppSettings>().unwrap(), AppSettings::AllowLeadingHyphen);
|
||||
assert_eq!("hidepossiblevaluesinhelp".parse::<AppSettings>().unwrap(), AppSettings::HidePossibleValuesInHelp);
|
||||
assert_eq!("coloredhelp".parse::<AppSettings>().unwrap(), AppSettings::ColoredHelp);
|
||||
assert_eq!("hidden".parse::<AppSettings>().unwrap(), AppSettings::Hidden);
|
||||
assert_eq!("subcommandsnegatereqs".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::SubcommandsNegateReqs);
|
||||
assert_eq!("subcommandsrequired".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::SubcommandRequired);
|
||||
assert_eq!("argrequiredelsehelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::ArgRequiredElseHelp);
|
||||
assert_eq!("globalversion".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::GlobalVersion);
|
||||
assert_eq!("versionlesssubcommands".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::VersionlessSubcommands);
|
||||
assert_eq!("unifiedhelpmessage".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::UnifiedHelpMessage);
|
||||
assert_eq!("waitonerror".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::WaitOnError);
|
||||
assert_eq!("subcommandrequiredelsehelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::SubcommandRequiredElseHelp);
|
||||
assert_eq!("allowexternalsubcommands".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::AllowExternalSubcommands);
|
||||
assert_eq!("trailingvararg".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::TrailingVarArg);
|
||||
assert_eq!("nobinaryname".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::NoBinaryName);
|
||||
assert_eq!("strictutf8".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::StrictUtf8);
|
||||
assert_eq!("allowinvalidutf8".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::AllowInvalidUtf8);
|
||||
assert_eq!("allowleadinghyphen".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::AllowLeadingHyphen);
|
||||
assert_eq!("hidepossiblevaluesinhelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::HidePossibleValuesInHelp);
|
||||
assert_eq!("coloredhelp".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::ColoredHelp);
|
||||
assert_eq!("hidden".parse::<AppSettings>().unwrap(),
|
||||
AppSettings::Hidden);
|
||||
assert!("hahahaha".parse::<AppSettings>().is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -7,7 +7,7 @@ use yaml_rust::Yaml;
|
|||
use vec_map::VecMap;
|
||||
|
||||
use usage_parser::UsageParser;
|
||||
use args::settings::{ArgSettings, ArgFlags};
|
||||
use args::settings::{ArgFlags, ArgSettings};
|
||||
|
||||
/// The abstract representation of a command line argument. Used to set all the options and
|
||||
/// relationships that define a valid argument for the program.
|
||||
|
@ -31,7 +31,9 @@ use args::settings::{ArgSettings, ArgFlags};
|
|||
/// let input = Arg::from_usage("-i, --input=[FILE] 'Provides an input file to the program'");
|
||||
/// ```
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Arg<'a, 'b> where 'a: 'b {
|
||||
pub struct Arg<'a, 'b>
|
||||
where 'a: 'b
|
||||
{
|
||||
#[doc(hidden)]
|
||||
pub name: &'a str,
|
||||
#[doc(hidden)]
|
||||
|
@ -119,10 +121,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// # ;
|
||||
/// ```
|
||||
pub fn with_name(n: &'a str) -> Self {
|
||||
Arg {
|
||||
name: n,
|
||||
..Default::default()
|
||||
}
|
||||
Arg { name: n, ..Default::default() }
|
||||
}
|
||||
|
||||
/// Creates a new instance of `Arg` from a .yml (YAML) file.
|
||||
|
@ -219,9 +218,11 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
a.setb(ArgSettings::RequiredUnlessAll);
|
||||
a
|
||||
}
|
||||
s => panic!("Unknown Arg setting '{}' in YAML file for arg '{}'",
|
||||
s,
|
||||
name_str),
|
||||
s => {
|
||||
panic!("Unknown Arg setting '{}' in YAML file for arg '{}'",
|
||||
s,
|
||||
name_str)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -328,7 +329,8 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
///
|
||||
/// ### Help String
|
||||
///
|
||||
/// The help string is denoted between a pair of single quotes `''` and may contain any characters.
|
||||
/// The help string is denoted between a pair of single quotes `''` and may contain any
|
||||
/// characters.
|
||||
///
|
||||
/// Example help strings are as follows:
|
||||
///
|
||||
|
@ -478,7 +480,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// helptest
|
||||
///
|
||||
/// USAGE:
|
||||
/// helptest [FLAGS]
|
||||
/// helptest [FLAGS]
|
||||
///
|
||||
/// FLAGS:
|
||||
/// --config Some help text describing the --config arg
|
||||
|
@ -538,7 +540,11 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::MissingRequiredArgument);
|
||||
/// ```
|
||||
pub fn required(self, r: bool) -> Self {
|
||||
if r { self.set(ArgSettings::Required) } else { self.unset(ArgSettings::Required) }
|
||||
if r {
|
||||
self.set(ArgSettings::Required)
|
||||
} else {
|
||||
self.unset(ArgSettings::Required)
|
||||
}
|
||||
}
|
||||
|
||||
/// Sets an arg that override this arg's required setting. (i.e. this arg will be required
|
||||
|
@ -1078,7 +1084,11 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert_eq!(m.value_of("mode"), Some("fast"));
|
||||
/// ```
|
||||
pub fn takes_value(self, tv: bool) -> Self {
|
||||
if tv { self.set(ArgSettings::TakesValue) } else { self.unset(ArgSettings::TakesValue) }
|
||||
if tv {
|
||||
self.set(ArgSettings::TakesValue)
|
||||
} else {
|
||||
self.unset(ArgSettings::TakesValue)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies the index of a positional argument **starting at** 1.
|
||||
|
@ -1140,8 +1150,8 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// because it isn't possible to more occurrences than values for options. Because multiple
|
||||
/// values are allowed, `--option val1 val2 val3` is perfectly valid, be careful when designing
|
||||
/// a CLI where positional arguments are expectd after a option which accepts multiple values,
|
||||
/// as `clap` will continue parsing *values* until it reaches the max or specific number of values defined, or another flag
|
||||
/// or option.
|
||||
/// as `clap` will continue parsing *values* until it reaches the max or specific number of
|
||||
/// values defined, or another flag or option.
|
||||
///
|
||||
/// **Pro Tip**:
|
||||
///
|
||||
|
@ -1269,7 +1279,11 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert_eq!(res.unwrap_err().kind, ErrorKind::UnknownArgument);
|
||||
/// ```
|
||||
pub fn multiple(self, multi: bool) -> Self {
|
||||
if multi { self.set(ArgSettings::Multiple) } else { self.unset(ArgSettings::Multiple) }
|
||||
if multi {
|
||||
self.set(ArgSettings::Multiple)
|
||||
} else {
|
||||
self.unset(ArgSettings::Multiple)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies that an argument can be matched to all child subcommands.
|
||||
|
@ -1313,7 +1327,11 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// assert!(sub_m.is_present("verb"));
|
||||
/// ```
|
||||
pub fn global(self, g: bool) -> Self {
|
||||
if g { self.set(ArgSettings::Global) } else { self.unset(ArgSettings::Global) }
|
||||
if g {
|
||||
self.set(ArgSettings::Global)
|
||||
} else {
|
||||
self.unset(ArgSettings::Global)
|
||||
}
|
||||
}
|
||||
|
||||
/// Allows an argument to accept explicitly empty values. An empty value must be specified at
|
||||
|
@ -1390,14 +1408,18 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// helptest
|
||||
///
|
||||
/// USAGE:
|
||||
/// helptest [FLAGS]
|
||||
/// helptest [FLAGS]
|
||||
///
|
||||
/// FLAGS:
|
||||
/// -h, --help Prints help information
|
||||
/// -V, --version Prints version information
|
||||
/// ```
|
||||
pub fn hidden(self, h: bool) -> Self {
|
||||
if h { self.set(ArgSettings::Hidden) } else { self.unset(ArgSettings::Hidden) }
|
||||
if h {
|
||||
self.set(ArgSettings::Hidden)
|
||||
} else {
|
||||
self.unset(ArgSettings::Hidden)
|
||||
}
|
||||
}
|
||||
|
||||
/// Specifies a list of possible values for this argument. At runtime, `clap` verifies that only
|
||||
|
@ -1857,7 +1879,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// valnames
|
||||
///
|
||||
/// USAGE:
|
||||
/// valnames [FLAGS] [OPTIONS]
|
||||
/// valnames [FLAGS] [OPTIONS]
|
||||
///
|
||||
/// FLAGS:
|
||||
/// -h, --help Prints help information
|
||||
|
@ -1869,7 +1891,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
pub fn value_names(mut self, names: &[&'b str]) -> Self {
|
||||
self.setb(ArgSettings::TakesValue);
|
||||
if let Some(ref mut vals) = self.val_names {
|
||||
let mut l = vals.len();
|
||||
let mut l = vals.len();
|
||||
for s in names {
|
||||
vals.insert(l, s);
|
||||
l += 1;
|
||||
|
@ -1918,7 +1940,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
/// valnames
|
||||
///
|
||||
/// USAGE:
|
||||
/// valnames [FLAGS] [OPTIONS]
|
||||
/// valnames [FLAGS] [OPTIONS]
|
||||
///
|
||||
/// FLAGS:
|
||||
/// -h, --help Prints help information
|
||||
|
@ -2112,8 +2134,7 @@ impl<'a, 'b> Arg<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>>
|
||||
for Arg<'a, 'b> {
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for Arg<'a, 'b> {
|
||||
fn from(a: &'z Arg<'a, 'b>) -> Self {
|
||||
Arg {
|
||||
name: a.name,
|
||||
|
|
|
@ -42,25 +42,24 @@ impl<'n, 'e> Default for FlagBuilder<'n, 'e> {
|
|||
|
||||
impl<'n, 'e> FlagBuilder<'n, 'e> {
|
||||
pub fn new(name: &'n str) -> Self {
|
||||
FlagBuilder {
|
||||
name: name,
|
||||
..Default::default()
|
||||
}
|
||||
FlagBuilder { name: name, ..Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'z> From<&'z Arg<'a, 'b>> for FlagBuilder<'a, 'b> {
|
||||
fn from(a: &'z Arg<'a, 'b>) -> Self {
|
||||
assert!(a.validator.is_none(),
|
||||
format!("The argument '{}' has a validator set, yet was parsed as a flag. Ensure \
|
||||
.takes_value(true) or .index(u64) is set.", a.name));
|
||||
format!("The argument '{}' has a validator set, yet was parsed as a flag. Ensure \
|
||||
.takes_value(true) or .index(u64) is set.",
|
||||
a.name));
|
||||
assert!(a.possible_vals.is_none(),
|
||||
format!("The argument '{}' cannot have a specific value set because it doesn't \
|
||||
format!("The argument '{}' cannot have a specific value set because it doesn't \
|
||||
have takes_value(true) set",
|
||||
a.name));
|
||||
a.name));
|
||||
assert!(!a.is_set(ArgSettings::Required),
|
||||
format!("The argument '{}' cannot be required because it's a flag, perhaps you forgot \
|
||||
takes_value(true)?", a.name));
|
||||
format!("The argument '{}' cannot be required because it's a flag, perhaps you \
|
||||
forgot takes_value(true)?",
|
||||
a.name));
|
||||
// No need to check for index() or takes_value() as that is handled above
|
||||
|
||||
FlagBuilder {
|
||||
|
@ -104,31 +103,75 @@ impl<'n, 'e> Clone for FlagBuilder<'n, 'e> {
|
|||
}
|
||||
|
||||
impl<'n, 'e> AnyArg<'n, 'e> for FlagBuilder<'n, 'e> {
|
||||
fn name(&self) -> &'n str { self.name }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { self.overrides.as_ref().map(|o| &o[..]) }
|
||||
fn requires(&self) -> Option<&[&'e str]> { self.requires.as_ref().map(|o| &o[..]) }
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { self.blacklist.as_ref().map(|o| &o[..]) }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { None }
|
||||
fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
|
||||
fn has_switch(&self) -> bool { true }
|
||||
fn takes_value(&self) -> bool { false }
|
||||
fn set(&mut self, s: ArgSettings) { self.settings.set(s) }
|
||||
fn max_vals(&self) -> Option<u64> { None }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { None }
|
||||
fn num_vals(&self) -> Option<u64> { None }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { None }
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> { None }
|
||||
fn min_vals(&self) -> Option<u64> { None }
|
||||
fn short(&self) -> Option<char> { self.short }
|
||||
fn long(&self) -> Option<&'e str> { self.long }
|
||||
fn val_delim(&self) -> Option<char> { None }
|
||||
fn help(&self) -> Option<&'e str> { self.help }
|
||||
fn default_val(&self) -> Option<&'n str> { None }
|
||||
fn longest_filter(&self) -> bool { self.long.is_some() }
|
||||
fn name(&self) -> &'n str {
|
||||
self.name
|
||||
}
|
||||
fn overrides(&self) -> Option<&[&'e str]> {
|
||||
self.overrides.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn requires(&self) -> Option<&[&'e str]> {
|
||||
self.requires.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> {
|
||||
self.blacklist.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn required_unless(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn is_set(&self, s: ArgSettings) -> bool {
|
||||
self.settings.is_set(s)
|
||||
}
|
||||
fn has_switch(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn takes_value(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn set(&mut self, s: ArgSettings) {
|
||||
self.settings.set(s)
|
||||
}
|
||||
fn max_vals(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> {
|
||||
None
|
||||
}
|
||||
fn num_vals(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> {
|
||||
None
|
||||
}
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
|
||||
None
|
||||
}
|
||||
fn min_vals(&self) -> Option<u64> {
|
||||
None
|
||||
}
|
||||
fn short(&self) -> Option<char> {
|
||||
self.short
|
||||
}
|
||||
fn long(&self) -> Option<&'e str> {
|
||||
self.long
|
||||
}
|
||||
fn val_delim(&self) -> Option<char> {
|
||||
None
|
||||
}
|
||||
fn help(&self) -> Option<&'e str> {
|
||||
self.help
|
||||
}
|
||||
fn default_val(&self) -> Option<&'n str> {
|
||||
None
|
||||
}
|
||||
fn longest_filter(&self) -> bool {
|
||||
self.long.is_some()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> DispOrder for FlagBuilder<'n, 'e> {
|
||||
fn disp_ord(&self) -> usize { self.disp_ord }
|
||||
fn disp_ord(&self) -> usize {
|
||||
self.disp_ord
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -57,16 +57,14 @@ impl<'n, 'e> Default for OptBuilder<'n, 'e> {
|
|||
|
||||
impl<'n, 'e> OptBuilder<'n, 'e> {
|
||||
pub fn new(name: &'n str) -> Self {
|
||||
OptBuilder {
|
||||
name: name,
|
||||
..Default::default()
|
||||
}
|
||||
OptBuilder { name: name, ..Default::default() }
|
||||
}
|
||||
|
||||
pub fn from_arg(a: &Arg<'n, 'e>, reqs: &mut Vec<&'e str>) -> Self {
|
||||
assert!(a.short.is_some() || a.long.is_some(),
|
||||
format!("Argument \"{}\" has takes_value(true), yet neither a short() or long() \
|
||||
was supplied", a.name));
|
||||
format!("Argument \"{}\" has takes_value(true), yet neither a short() or long() \
|
||||
was supplied",
|
||||
a.name));
|
||||
|
||||
// No need to check for .index() as that is handled above
|
||||
let mut ob = OptBuilder {
|
||||
|
@ -105,12 +103,13 @@ impl<'n, 'e> OptBuilder<'n, 'e> {
|
|||
// If the arg is required, add all it's requirements to master required list
|
||||
if a.is_set(ArgSettings::Required) {
|
||||
if let Some(ref areqs) = a.requires {
|
||||
for r in areqs { reqs.push(*r); }
|
||||
for r in areqs {
|
||||
reqs.push(*r);
|
||||
}
|
||||
}
|
||||
}
|
||||
ob
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'n, 'e> Display for OptBuilder<'n, 'e> {
|
||||
|
@ -128,7 +127,9 @@ impl<'n, 'e> Display for OptBuilder<'n, 'e> {
|
|||
let mut it = vec.iter().peekable();
|
||||
while let Some((_, val)) = it.next() {
|
||||
try!(write!(f, "<{}>", val));
|
||||
if it.peek().is_some() { try!(write!(f, " ")); }
|
||||
if it.peek().is_some() {
|
||||
try!(write!(f, " "));
|
||||
}
|
||||
}
|
||||
let num = vec.len();
|
||||
if self.is_set(ArgSettings::Multiple) && num == 1 {
|
||||
|
@ -138,10 +139,19 @@ impl<'n, 'e> Display for OptBuilder<'n, 'e> {
|
|||
let mut it = (0..num).peekable();
|
||||
while let Some(_) = it.next() {
|
||||
try!(write!(f, "<{}>", self.name));
|
||||
if it.peek().is_some() { try!(write!(f, " ")); }
|
||||
if it.peek().is_some() {
|
||||
try!(write!(f, " "));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
try!(write!(f, "<{}>{}", self.name, if self.is_set(ArgSettings::Multiple) { "..." } else { "" }));
|
||||
try!(write!(f,
|
||||
"<{}>{}",
|
||||
self.name,
|
||||
if self.is_set(ArgSettings::Multiple) {
|
||||
"..."
|
||||
} else {
|
||||
""
|
||||
}));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -174,34 +184,76 @@ impl<'n, 'e> Clone for OptBuilder<'n, 'e> {
|
|||
}
|
||||
|
||||
impl<'n, 'e> AnyArg<'n, 'e> for OptBuilder<'n, 'e> {
|
||||
fn name(&self) -> &'n str { self.name }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { self.overrides.as_ref().map(|o| &o[..]) }
|
||||
fn requires(&self) -> Option<&[&'e str]> { self.requires.as_ref().map(|o| &o[..]) }
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { self.blacklist.as_ref().map(|o| &o[..]) }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { self.r_unless.as_ref().map(|o| &o[..]) }
|
||||
fn name(&self) -> &'n str {
|
||||
self.name
|
||||
}
|
||||
fn overrides(&self) -> Option<&[&'e str]> {
|
||||
self.overrides.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn requires(&self) -> Option<&[&'e str]> {
|
||||
self.requires.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> {
|
||||
self.blacklist.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn required_unless(&self) -> Option<&[&'e str]> {
|
||||
self.r_unless.as_ref().map(|o| &o[..])
|
||||
}
|
||||
#[cfg_attr(feature = "lints", allow(map_clone))]
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { self.val_names.as_ref().map(|o| o) }
|
||||
fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
|
||||
fn has_switch(&self) -> bool { true }
|
||||
fn set(&mut self, s: ArgSettings) { self.settings.set(s) }
|
||||
fn max_vals(&self) -> Option<u64> { self.max_vals }
|
||||
fn num_vals(&self) -> Option<u64> { self.num_vals }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { self.possible_vals.as_ref().map(|o| &o[..]) }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> {
|
||||
self.val_names.as_ref().map(|o| o)
|
||||
}
|
||||
fn is_set(&self, s: ArgSettings) -> bool {
|
||||
self.settings.is_set(s)
|
||||
}
|
||||
fn has_switch(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn set(&mut self, s: ArgSettings) {
|
||||
self.settings.set(s)
|
||||
}
|
||||
fn max_vals(&self) -> Option<u64> {
|
||||
self.max_vals
|
||||
}
|
||||
fn num_vals(&self) -> Option<u64> {
|
||||
self.num_vals
|
||||
}
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> {
|
||||
self.possible_vals.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
|
||||
self.validator.as_ref()
|
||||
}
|
||||
fn min_vals(&self) -> Option<u64> { self.min_vals }
|
||||
fn short(&self) -> Option<char> { self.short }
|
||||
fn long(&self) -> Option<&'e str> { self.long }
|
||||
fn val_delim(&self) -> Option<char> { self.val_delim }
|
||||
fn takes_value(&self) -> bool { true }
|
||||
fn help(&self) -> Option<&'e str> { self.help }
|
||||
fn default_val(&self) -> Option<&'n str> { self.default_val }
|
||||
fn longest_filter(&self) -> bool { true }
|
||||
fn min_vals(&self) -> Option<u64> {
|
||||
self.min_vals
|
||||
}
|
||||
fn short(&self) -> Option<char> {
|
||||
self.short
|
||||
}
|
||||
fn long(&self) -> Option<&'e str> {
|
||||
self.long
|
||||
}
|
||||
fn val_delim(&self) -> Option<char> {
|
||||
self.val_delim
|
||||
}
|
||||
fn takes_value(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn help(&self) -> Option<&'e str> {
|
||||
self.help
|
||||
}
|
||||
fn default_val(&self) -> Option<&'n str> {
|
||||
self.default_val
|
||||
}
|
||||
fn longest_filter(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> DispOrder for OptBuilder<'n, 'e> {
|
||||
fn disp_ord(&self) -> usize { self.disp_ord }
|
||||
fn disp_ord(&self) -> usize {
|
||||
self.disp_ord
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -65,8 +65,9 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
|
|||
|
||||
pub fn from_arg(a: &Arg<'n, 'e>, idx: u64, reqs: &mut Vec<&'e str>) -> Self {
|
||||
debug_assert!(a.short.is_none() || a.long.is_none(),
|
||||
format!("Argument \"{}\" has conflicting requirements, both index() and short(), \
|
||||
or long(), were supplied", a.name));
|
||||
format!("Argument \"{}\" has conflicting requirements, both index() and \
|
||||
short(), or long(), were supplied",
|
||||
a.name));
|
||||
|
||||
// Create the Positional Argument Builder with each HashSet = None to only
|
||||
// allocate
|
||||
|
@ -90,9 +91,8 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
|
|||
r_unless: a.r_unless.clone(),
|
||||
..Default::default()
|
||||
};
|
||||
if a.max_vals.is_some()
|
||||
|| a.min_vals.is_some()
|
||||
|| (a.num_vals.is_some() && a.num_vals.unwrap() > 1) {
|
||||
if a.max_vals.is_some() || a.min_vals.is_some() ||
|
||||
(a.num_vals.is_some() && a.num_vals.unwrap() > 1) {
|
||||
pb.settings.set(ArgSettings::Multiple);
|
||||
}
|
||||
if let Some(ref p) = a.validator {
|
||||
|
@ -101,25 +101,36 @@ impl<'n, 'e> PosBuilder<'n, 'e> {
|
|||
// If the arg is required, add all it's requirements to master required list
|
||||
if a.is_set(ArgSettings::Required) {
|
||||
if let Some(ref areqs) = a.requires {
|
||||
for r in areqs { reqs.push(*r); }
|
||||
for r in areqs {
|
||||
reqs.push(*r);
|
||||
}
|
||||
}
|
||||
}
|
||||
pb
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
impl<'n, 'e> Display for PosBuilder<'n, 'e> {
|
||||
fn fmt(&self, f: &mut Formatter) -> Result {
|
||||
if self.settings.is_set(ArgSettings::Required) {
|
||||
if let Some(ref names) = self.val_names {
|
||||
try!(write!(f, "{}", names.values().map(|n| format!("<{}>", n)).collect::<Vec<_>>().join(" ")));
|
||||
try!(write!(f,
|
||||
"{}",
|
||||
names.values()
|
||||
.map(|n| format!("<{}>", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")));
|
||||
} else {
|
||||
try!(write!(f, "<{}>", self.name));
|
||||
}
|
||||
} else {
|
||||
if let Some(ref names) = self.val_names {
|
||||
try!(write!(f, "{}", names.values().map(|n| format!("[{}]", n)).collect::<Vec<_>>().join(" ")));
|
||||
try!(write!(f,
|
||||
"{}",
|
||||
names.values()
|
||||
.map(|n| format!("[{}]", n))
|
||||
.collect::<Vec<_>>()
|
||||
.join(" ")));
|
||||
} else {
|
||||
try!(write!(f, "[{}]", self.name));
|
||||
}
|
||||
|
@ -157,33 +168,75 @@ impl<'n, 'e> Clone for PosBuilder<'n, 'e> {
|
|||
}
|
||||
|
||||
impl<'n, 'e> AnyArg<'n, 'e> for PosBuilder<'n, 'e> {
|
||||
fn name(&self) -> &'n str { self.name }
|
||||
fn overrides(&self) -> Option<&[&'e str]> { self.overrides.as_ref().map(|o| &o[..]) }
|
||||
fn requires(&self) -> Option<&[&'e str]> { self.requires.as_ref().map(|o| &o[..]) }
|
||||
fn blacklist(&self) -> Option<&[&'e str]> { self.blacklist.as_ref().map(|o| &o[..]) }
|
||||
fn required_unless(&self) -> Option<&[&'e str]> { self.r_unless.as_ref().map(|o| &o[..]) }
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> { self.val_names.as_ref() }
|
||||
fn is_set(&self, s: ArgSettings) -> bool { self.settings.is_set(s) }
|
||||
fn set(&mut self, s: ArgSettings) { self.settings.set(s) }
|
||||
fn has_switch(&self) -> bool { false }
|
||||
fn max_vals(&self) -> Option<u64> { self.max_vals }
|
||||
fn num_vals(&self) -> Option<u64> { self.num_vals }
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> { self.possible_vals.as_ref().map(|o| &o[..]) }
|
||||
fn name(&self) -> &'n str {
|
||||
self.name
|
||||
}
|
||||
fn overrides(&self) -> Option<&[&'e str]> {
|
||||
self.overrides.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn requires(&self) -> Option<&[&'e str]> {
|
||||
self.requires.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn blacklist(&self) -> Option<&[&'e str]> {
|
||||
self.blacklist.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn required_unless(&self) -> Option<&[&'e str]> {
|
||||
self.r_unless.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn val_names(&self) -> Option<&VecMap<&'e str>> {
|
||||
self.val_names.as_ref()
|
||||
}
|
||||
fn is_set(&self, s: ArgSettings) -> bool {
|
||||
self.settings.is_set(s)
|
||||
}
|
||||
fn set(&mut self, s: ArgSettings) {
|
||||
self.settings.set(s)
|
||||
}
|
||||
fn has_switch(&self) -> bool {
|
||||
false
|
||||
}
|
||||
fn max_vals(&self) -> Option<u64> {
|
||||
self.max_vals
|
||||
}
|
||||
fn num_vals(&self) -> Option<u64> {
|
||||
self.num_vals
|
||||
}
|
||||
fn possible_vals(&self) -> Option<&[&'e str]> {
|
||||
self.possible_vals.as_ref().map(|o| &o[..])
|
||||
}
|
||||
fn validator(&self) -> Option<&Rc<Fn(String) -> StdResult<(), String>>> {
|
||||
self.validator.as_ref()
|
||||
}
|
||||
fn min_vals(&self) -> Option<u64> { self.min_vals }
|
||||
fn short(&self) -> Option<char> { None }
|
||||
fn long(&self) -> Option<&'e str> { None }
|
||||
fn val_delim(&self) -> Option<char> { self.val_delim }
|
||||
fn takes_value(&self) -> bool { true }
|
||||
fn help(&self) -> Option<&'e str> { self.help }
|
||||
fn default_val(&self) -> Option<&'n str> { self.default_val }
|
||||
fn longest_filter(&self) -> bool { true }
|
||||
fn min_vals(&self) -> Option<u64> {
|
||||
self.min_vals
|
||||
}
|
||||
fn short(&self) -> Option<char> {
|
||||
None
|
||||
}
|
||||
fn long(&self) -> Option<&'e str> {
|
||||
None
|
||||
}
|
||||
fn val_delim(&self) -> Option<char> {
|
||||
self.val_delim
|
||||
}
|
||||
fn takes_value(&self) -> bool {
|
||||
true
|
||||
}
|
||||
fn help(&self) -> Option<&'e str> {
|
||||
self.help
|
||||
}
|
||||
fn default_val(&self) -> Option<&'n str> {
|
||||
self.default_val
|
||||
}
|
||||
fn longest_filter(&self) -> bool {
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
impl<'n, 'e> DispOrder for PosBuilder<'n, 'e> {
|
||||
fn disp_ord(&self) -> usize { self.disp_ord }
|
||||
fn disp_ord(&self) -> usize {
|
||||
self.disp_ord
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
|
|
@ -102,7 +102,8 @@ impl<'a> ArgMatcher<'a> {
|
|||
}
|
||||
|
||||
pub fn needs_more_vals<'b, A>(&self, o: &A) -> bool
|
||||
where A: AnyArg<'a, 'b> {
|
||||
where A: AnyArg<'a, 'b>
|
||||
{
|
||||
if let Some(ma) = self.get(o.name()) {
|
||||
if let Some(num) = o.num_vals() {
|
||||
return if o.is_set(ArgSettings::Multiple) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use std::ffi::{OsString, OsStr};
|
||||
use std::ffi::{OsStr, OsString};
|
||||
use std::collections::HashMap;
|
||||
use std::iter::Map;
|
||||
use std::slice;
|
||||
|
@ -78,7 +78,9 @@ impl<'a> Default for ArgMatches<'a> {
|
|||
|
||||
impl<'a> ArgMatches<'a> {
|
||||
#[doc(hidden)]
|
||||
pub fn new() -> Self { ArgMatches { ..Default::default() } }
|
||||
pub fn new() -> Self {
|
||||
ArgMatches { ..Default::default() }
|
||||
}
|
||||
|
||||
/// Gets the value of a specific option or positional argument (i.e. an argument that takes
|
||||
/// an additional value at runtime). If the option wasn't present at runtime
|
||||
|
@ -165,7 +167,9 @@ impl<'a> ArgMatches<'a> {
|
|||
/// assert_eq!(&*m.value_of_os("arg").unwrap().as_bytes(), [b'H', b'i', b' ', 0xe9, b'!']);
|
||||
/// ```
|
||||
pub fn value_of_os<S: AsRef<str>>(&self, name: S) -> Option<&OsStr> {
|
||||
self.args.get(name.as_ref()).map_or(None, |arg| arg.vals.values().nth(0).map(|v| v.as_os_str()))
|
||||
self.args
|
||||
.get(name.as_ref())
|
||||
.map_or(None, |arg| arg.vals.values().nth(0).map(|v| v.as_os_str()))
|
||||
}
|
||||
|
||||
/// Gets an Iterator of values of a specific argument (i.e. an argument that takes multiple
|
||||
|
@ -192,7 +196,9 @@ impl<'a> ArgMatches<'a> {
|
|||
/// ```
|
||||
pub fn values_of<S: AsRef<str>>(&'a self, name: S) -> Option<Values<'a>> {
|
||||
if let Some(ref arg) = self.args.get(name.as_ref()) {
|
||||
fn to_str_slice(o: &OsString) -> &str { o.to_str().expect(INVALID_UTF8) }
|
||||
fn to_str_slice(o: &OsString) -> &str {
|
||||
o.to_str().expect(INVALID_UTF8)
|
||||
}
|
||||
let to_str_slice: fn(&OsString) -> &str = to_str_slice; // coerce to fn pointer
|
||||
return Some(Values { iter: arg.vals.values().map(to_str_slice) });
|
||||
}
|
||||
|
@ -222,7 +228,8 @@ impl<'a> ArgMatches<'a> {
|
|||
/// ```
|
||||
pub fn values_of_lossy<S: AsRef<str>>(&'a self, name: S) -> Option<Vec<String>> {
|
||||
if let Some(ref arg) = self.args.get(name.as_ref()) {
|
||||
return Some(arg.vals.values()
|
||||
return Some(arg.vals
|
||||
.values()
|
||||
.map(|v| v.to_string_lossy().into_owned())
|
||||
.collect());
|
||||
}
|
||||
|
@ -256,7 +263,9 @@ impl<'a> ArgMatches<'a> {
|
|||
/// assert_eq!(itr.next(), None);
|
||||
/// ```
|
||||
pub fn values_of_os<S: AsRef<str>>(&'a self, name: S) -> Option<OsValues<'a>> {
|
||||
fn to_str_slice(o: &OsString) -> &OsStr { &*o }
|
||||
fn to_str_slice(o: &OsString) -> &OsStr {
|
||||
&*o
|
||||
}
|
||||
let to_str_slice: fn(&'a OsString) -> &'a OsStr = to_str_slice; // coerce to fn pointer
|
||||
if let Some(ref arg) = self.args.get(name.as_ref()) {
|
||||
return Some(OsValues { iter: arg.vals.values().map(to_str_slice) });
|
||||
|
@ -360,7 +369,9 @@ impl<'a> ArgMatches<'a> {
|
|||
/// ```
|
||||
pub fn subcommand_matches<S: AsRef<str>>(&self, name: S) -> Option<&ArgMatches<'a>> {
|
||||
if let Some(ref s) = self.subcommand {
|
||||
if s.name == name.as_ref() { return Some(&s.matches) }
|
||||
if s.name == name.as_ref() {
|
||||
return Some(&s.matches);
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
@ -498,26 +509,32 @@ impl<'a> ArgMatches<'a> {
|
|||
#[derive(Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct Values<'a> {
|
||||
iter: Map<vec_map::Values<'a, OsString>, fn(&'a OsString) -> &'a str>
|
||||
iter: Map<vec_map::Values<'a, OsString>, fn(&'a OsString) -> &'a str>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for Values<'a> {
|
||||
type Item = &'a str;
|
||||
|
||||
fn next(&mut self) -> Option<&'a str> { self.iter.next() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
self.iter.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DoubleEndedIterator for Values<'a> {
|
||||
fn next_back(&mut self) -> Option<&'a str> { self.iter.next_back() }
|
||||
fn next_back(&mut self) -> Option<&'a str> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
||||
/// An iterator over the key-value pairs of a map.
|
||||
#[derive(Clone)]
|
||||
pub struct Iter<'a, V:'a> {
|
||||
pub struct Iter<'a, V: 'a> {
|
||||
front: usize,
|
||||
back: usize,
|
||||
iter: slice::Iter<'a, Option<V>>
|
||||
iter: slice::Iter<'a, Option<V>>,
|
||||
}
|
||||
|
||||
impl<'a, V> Iterator for Iter<'a, V> {
|
||||
|
@ -562,16 +579,22 @@ impl<'a, V> DoubleEndedIterator for Iter<'a, V> {
|
|||
#[derive(Clone)]
|
||||
#[allow(missing_debug_implementations)]
|
||||
pub struct OsValues<'a> {
|
||||
iter: Map<vec_map::Values<'a, OsString>, fn(&'a OsString) -> &'a OsStr>
|
||||
iter: Map<vec_map::Values<'a, OsString>, fn(&'a OsString) -> &'a OsStr>,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for OsValues<'a> {
|
||||
type Item = &'a OsStr;
|
||||
|
||||
fn next(&mut self) -> Option<&'a OsStr> { self.iter.next() }
|
||||
fn size_hint(&self) -> (usize, Option<usize>) { self.iter.size_hint() }
|
||||
fn next(&mut self) -> Option<&'a OsStr> {
|
||||
self.iter.next()
|
||||
}
|
||||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
self.iter.size_hint()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> DoubleEndedIterator for OsValues<'a> {
|
||||
fn next_back(&mut self) -> Option<&'a OsStr> { self.iter.next_back() }
|
||||
fn next_back(&mut self) -> Option<&'a OsStr> {
|
||||
self.iter.next_back()
|
||||
}
|
||||
}
|
||||
|
|
|
@ -318,7 +318,10 @@ impl<'a> From<&'a BTreeMap<Yaml, Yaml>> for ArgGroup<'a> {
|
|||
let name_yml = b.keys().nth(0).expect("failed to get name");
|
||||
let name_str = name_yml.as_str().expect("failed to convert name to str");
|
||||
a.name = name_str;
|
||||
b.get(name_yml).expect("failed to get name_str").as_hash().expect("failed to convert to a hash")
|
||||
b.get(name_yml)
|
||||
.expect("failed to get name_str")
|
||||
.as_hash()
|
||||
.expect("failed to convert to a hash")
|
||||
} else {
|
||||
b
|
||||
};
|
||||
|
@ -362,10 +365,12 @@ impl<'a> From<&'a BTreeMap<Yaml, Yaml>> for ArgGroup<'a> {
|
|||
}
|
||||
a
|
||||
}
|
||||
s => panic!("Unknown ArgGroup setting '{}' in YAML file for \
|
||||
s => {
|
||||
panic!("Unknown ArgGroup setting '{}' in YAML file for \
|
||||
ArgGroup '{}'",
|
||||
s,
|
||||
a.name),
|
||||
s,
|
||||
a.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,14 +425,17 @@ mod test {
|
|||
let reqs = vec!["r1", "r2", "r3", "r4"];
|
||||
let confs = vec!["c1", "c2", "c3", "c4"];
|
||||
|
||||
let debug_str =
|
||||
format!("{{\n\
|
||||
let debug_str = format!("{{\n\
|
||||
\tname: \"test\",\n\
|
||||
\targs: {:?},\n\
|
||||
\trequired: {:?},\n\
|
||||
\trequires: {:?},\n\
|
||||
\tconflicts: {:?},\n\
|
||||
}}", args, true, Some(reqs), Some(confs));
|
||||
}}",
|
||||
args,
|
||||
true,
|
||||
Some(reqs),
|
||||
Some(confs));
|
||||
assert_eq!(&*format!("{:?}", g), &*debug_str);
|
||||
}
|
||||
|
||||
|
@ -459,8 +467,7 @@ mod test {
|
|||
#[cfg_attr(feature = "yaml", test)]
|
||||
fn test_yaml() {
|
||||
|
||||
let g_yaml =
|
||||
"name: test
|
||||
let g_yaml = "name: test
|
||||
args:
|
||||
- a1
|
||||
- a4
|
||||
|
@ -497,5 +504,4 @@ impl<'a> Clone for ArgGroup<'a> {
|
|||
conflicts: self.conflicts.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -21,5 +21,7 @@ impl Default for MatchedArg {
|
|||
}
|
||||
|
||||
impl MatchedArg {
|
||||
pub fn new() -> Self { MatchedArg::default() }
|
||||
pub fn new() -> Self {
|
||||
MatchedArg::default()
|
||||
}
|
||||
}
|
||||
|
|
190
src/errors.rs
190
src/errors.rs
|
@ -337,7 +337,8 @@ impl Error {
|
|||
/// Should the message be written to `stdout` or not
|
||||
pub fn use_stderr(&self) -> bool {
|
||||
match self.kind {
|
||||
ErrorKind::HelpDisplayed | ErrorKind::VersionDisplayed => false,
|
||||
ErrorKind::HelpDisplayed |
|
||||
ErrorKind::VersionDisplayed => false,
|
||||
_ => true,
|
||||
}
|
||||
}
|
||||
|
@ -364,18 +365,18 @@ impl Error {
|
|||
message: format!("{} The argument '{}' cannot be used with {}\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
match other {
|
||||
Some(name) => {
|
||||
let n = name.into();
|
||||
v.push(n.clone());
|
||||
format!("'{}'", Format::Warning(n))
|
||||
},
|
||||
None => "one or more of the other specified arguments".to_owned(),
|
||||
},
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
match other {
|
||||
Some(name) => {
|
||||
let n = name.into();
|
||||
v.push(n.clone());
|
||||
format!("'{}'", Format::Warning(n))
|
||||
}
|
||||
None => "one or more of the other specified arguments".to_owned(),
|
||||
},
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::ArgumentConflict,
|
||||
info: Some(v),
|
||||
}
|
||||
|
@ -391,10 +392,10 @@ impl Error {
|
|||
\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::EmptyValue,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
}
|
||||
|
@ -407,9 +408,10 @@ impl Error {
|
|||
A: AnyArg<'a, 'b> + Display,
|
||||
U: Display
|
||||
{
|
||||
let suffix = suggestions::did_you_mean_suffix(bad_val.as_ref(),
|
||||
good_vals.iter(),
|
||||
suggestions::DidYouMeanMessageStyle::EnumValue);
|
||||
let suffix =
|
||||
suggestions::did_you_mean_suffix(bad_val.as_ref(),
|
||||
good_vals.iter(),
|
||||
suggestions::DidYouMeanMessageStyle::EnumValue);
|
||||
|
||||
let mut sorted = vec![];
|
||||
for v in good_vals {
|
||||
|
@ -423,13 +425,13 @@ impl Error {
|
|||
{}\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(bad_val.as_ref()),
|
||||
Format::Warning(arg.to_string()),
|
||||
valid_values,
|
||||
suffix.0,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(bad_val.as_ref()),
|
||||
Format::Warning(arg.to_string()),
|
||||
valid_values,
|
||||
suffix.0,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::InvalidValue,
|
||||
info: Some(vec![arg.name().to_owned(), bad_val.as_ref().to_owned()]),
|
||||
}
|
||||
|
@ -450,14 +452,14 @@ impl Error {
|
|||
re-running with '{} {} {}'\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(&*s),
|
||||
Format::Good(did_you_mean.as_ref()),
|
||||
name,
|
||||
Format::Good("--"),
|
||||
&*s,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(&*s),
|
||||
Format::Good(did_you_mean.as_ref()),
|
||||
name,
|
||||
Format::Good("--"),
|
||||
&*s,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::InvalidSubcommand,
|
||||
info: Some(vec![s]),
|
||||
}
|
||||
|
@ -474,10 +476,10 @@ impl Error {
|
|||
USAGE:\n\t\
|
||||
{} help <subcommands>...\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(&*s),
|
||||
name,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(&*s),
|
||||
name,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::UnrecognizedSubcommand,
|
||||
info: Some(vec![s]),
|
||||
}
|
||||
|
@ -492,10 +494,10 @@ impl Error {
|
|||
message: format!("{} The following required arguments were not provided:{}\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
required,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
required,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::MissingRequiredArgument,
|
||||
info: None,
|
||||
}
|
||||
|
@ -510,10 +512,10 @@ impl Error {
|
|||
message: format!("{} '{}' requires a subcommand, but one was not provided\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(name),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(name),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::MissingSubcommand,
|
||||
info: None,
|
||||
}
|
||||
|
@ -528,9 +530,9 @@ impl Error {
|
|||
message: format!("{} Invalid UTF-8 was detected in one or more arguments\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::InvalidUtf8,
|
||||
info: None,
|
||||
}
|
||||
|
@ -548,11 +550,11 @@ impl Error {
|
|||
any more values\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(v),
|
||||
Format::Warning(arg.to_string()),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(v),
|
||||
Format::Warning(arg.to_string()),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::TooManyValues,
|
||||
info: Some(vec![arg.name().to_owned(), v.to_owned()]),
|
||||
}
|
||||
|
@ -568,17 +570,17 @@ impl Error {
|
|||
provided\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
Format::Warning(min_vals.to_string()),
|
||||
Format::Warning(curr_vals.to_string()),
|
||||
if curr_vals > 1 {
|
||||
"ere"
|
||||
} else {
|
||||
"as"
|
||||
},
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
Format::Warning(min_vals.to_string()),
|
||||
Format::Warning(curr_vals.to_string()),
|
||||
if curr_vals > 1 {
|
||||
"ere"
|
||||
} else {
|
||||
"as"
|
||||
},
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::TooFewValues,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
}
|
||||
|
@ -594,7 +596,12 @@ impl Error {
|
|||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
pub fn wrong_number_of_values<'a, 'b, A, S, U>(arg: &A, num_vals: u64, curr_vals: usize, suffix: S, usage: U) -> Self
|
||||
pub fn wrong_number_of_values<'a, 'b, A, S, U>(arg: &A,
|
||||
num_vals: u64,
|
||||
curr_vals: usize,
|
||||
suffix: S,
|
||||
usage: U)
|
||||
-> Self
|
||||
where A: AnyArg<'a, 'b> + Display,
|
||||
S: Display,
|
||||
U: Display
|
||||
|
@ -604,13 +611,13 @@ impl Error {
|
|||
provided\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
Format::Warning(num_vals.to_string()),
|
||||
Format::Warning(curr_vals.to_string()),
|
||||
suffix,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
Format::Warning(num_vals.to_string()),
|
||||
Format::Warning(curr_vals.to_string()),
|
||||
suffix,
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::WrongNumberOfValues,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
}
|
||||
|
@ -626,10 +633,10 @@ impl Error {
|
|||
be used multiple times\n\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(arg.to_string()),
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::UnexpectedMultipleUsage,
|
||||
info: Some(vec![arg.name().to_owned()]),
|
||||
}
|
||||
|
@ -642,18 +649,19 @@ impl Error {
|
|||
{
|
||||
let a = arg.into();
|
||||
Error {
|
||||
message: format!("{} Found argument '{}' which wasn't expected, or isn't valid in this context{}\n\
|
||||
message: format!("{} Found argument '{}' which wasn't expected, or isn't valid in \
|
||||
this context{}\n\
|
||||
{}\n\n\
|
||||
For more information try {}",
|
||||
Format::Error("error:"),
|
||||
Format::Warning(&*a),
|
||||
if did_you_mean.is_empty() {
|
||||
"\n".to_owned()
|
||||
} else {
|
||||
format!("{}\n", did_you_mean)
|
||||
},
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
Format::Error("error:"),
|
||||
Format::Warning(&*a),
|
||||
if did_you_mean.is_empty() {
|
||||
"\n".to_owned()
|
||||
} else {
|
||||
format!("{}\n", did_you_mean)
|
||||
},
|
||||
usage,
|
||||
Format::Good("--help")),
|
||||
kind: ErrorKind::UnknownArgument,
|
||||
info: Some(vec![a]),
|
||||
}
|
||||
|
@ -661,11 +669,13 @@ impl Error {
|
|||
|
||||
#[doc(hidden)]
|
||||
pub fn argument_not_found<A>(arg: A) -> Self
|
||||
where A: Into<String>,
|
||||
where A: Into<String>
|
||||
{
|
||||
let a = arg.into();
|
||||
Error {
|
||||
message: format!("{} The argument '{}' wasn't found", Format::Error("error:"), a.clone()),
|
||||
message: format!("{} The argument '{}' wasn't found",
|
||||
Format::Error("error:"),
|
||||
a.clone()),
|
||||
kind: ErrorKind::ArgumentNotFound,
|
||||
info: Some(vec![a]),
|
||||
}
|
||||
|
|
|
@ -28,7 +28,6 @@ impl<T: AsRef<str>> Format<T> {
|
|||
Format::Good(ref e) => Green.paint(e.as_ref()),
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#[cfg(all(feature = "color", not(target_os = "windows")))]
|
||||
|
|
|
@ -395,6 +395,7 @@
|
|||
unused_qualifications)]
|
||||
// clippy false positives, or ones we're ok with...
|
||||
#![cfg_attr(feature = "lints", allow(cyclomatic_complexity))]
|
||||
#![cfg_attr(feature = "lints", allow(doc_markdown))]
|
||||
// Only while bitflats uses "_first" inside it's macros
|
||||
#![cfg_attr(feature = "lints", allow(used_underscore_binding))]
|
||||
// Only while bitflats fails this lint
|
||||
|
@ -416,7 +417,7 @@ extern crate vec_map;
|
|||
|
||||
#[cfg(feature = "yaml")]
|
||||
pub use yaml_rust::YamlLoader;
|
||||
pub use args::{Arg, ArgGroup, ArgMatches, SubCommand, ArgSettings};
|
||||
pub use args::{Arg, ArgGroup, ArgMatches, ArgSettings, SubCommand};
|
||||
pub use app::{App, AppSettings};
|
||||
pub use fmt::Format;
|
||||
pub use errors::{Error, ErrorKind, Result};
|
||||
|
|
|
@ -372,8 +372,8 @@ macro_rules! crate_version {
|
|||
};
|
||||
}
|
||||
|
||||
/// Allows you to pull the authors for the app from your Cargo.toml at
|
||||
/// compile time as
|
||||
/// Allows you to pull the authors for the app from your Cargo.toml at
|
||||
/// compile time as
|
||||
/// "author1 lastname. <author1@example.com>",
|
||||
/// "author2 lastname. <author2@example.com>"
|
||||
///
|
||||
|
@ -403,7 +403,8 @@ macro_rules! clap_app {
|
|||
(@app ($builder:expr)) => { $builder };
|
||||
(@app ($builder:expr) (@arg $name:ident: $($tail:tt)*) $($tt:tt)*) => {
|
||||
clap_app!{ @app
|
||||
($builder.arg(clap_app!{ @arg ($crate::Arg::with_name(stringify!($name))) (-) $($tail)* }))
|
||||
($builder.arg(
|
||||
clap_app!{ @arg ($crate::Arg::with_name(stringify!($name))) (-) $($tail)* }))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
|
@ -413,7 +414,7 @@ macro_rules! clap_app {
|
|||
$($tt)*
|
||||
}
|
||||
};
|
||||
// Treat the application builder as an argument to set it's attributes
|
||||
// Treat the application builder as an argument to set it's attributes
|
||||
(@app ($builder:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => {
|
||||
clap_app!{ @app (clap_app!{ @arg ($builder) $($attr)* }) $($tt)* }
|
||||
};
|
||||
|
@ -423,7 +424,7 @@ macro_rules! clap_app {
|
|||
$($tt)*
|
||||
}
|
||||
};
|
||||
// Handle subcommand creation
|
||||
// Handle subcommand creation
|
||||
(@app ($builder:expr) (@subcommand $name:ident => $($tail:tt)*) $($tt:tt)*) => {
|
||||
clap_app!{ @app
|
||||
($builder.subcommand(
|
||||
|
@ -432,16 +433,16 @@ macro_rules! clap_app {
|
|||
$($tt)*
|
||||
}
|
||||
};
|
||||
// Yaml like function calls - used for setting various meta directly against the app
|
||||
// Yaml like function calls - used for setting various meta directly against the app
|
||||
(@app ($builder:expr) ($ident:ident: $($v:expr),*) $($tt:tt)*) => {
|
||||
// clap_app!{ @app ($builder.$ident($($v),*)) $($tt)* }
|
||||
// clap_app!{ @app ($builder.$ident($($v),*)) $($tt)* }
|
||||
clap_app!{ @app
|
||||
($builder.$ident($($v),*))
|
||||
$($tt)*
|
||||
}
|
||||
};
|
||||
|
||||
// Add members to group and continue argument handling with the parent builder
|
||||
// Add members to group and continue argument handling with the parent builder
|
||||
(@group ($builder:expr, $group:expr)) => { $builder.group($group) };
|
||||
(@group ($builder:expr, $group:expr) (@attributes $($attr:tt)*) $($tt:tt)*) => {
|
||||
clap_app!{ @group ($builder, clap_app!{ @arg ($group) (-) $($attr)* }) $($tt)* }
|
||||
|
@ -454,9 +455,9 @@ macro_rules! clap_app {
|
|||
}
|
||||
};
|
||||
|
||||
// No more tokens to munch
|
||||
// No more tokens to munch
|
||||
(@arg ($arg:expr) $modes:tt) => { $arg };
|
||||
// Shorthand tokens influenced by the usage_string
|
||||
// Shorthand tokens influenced by the usage_string
|
||||
(@arg ($arg:expr) $modes:tt --$long:ident $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg.long(stringify!($long))) $modes $($tail)* }
|
||||
};
|
||||
|
@ -478,42 +479,42 @@ macro_rules! clap_app {
|
|||
(@arg ($arg:expr) $modes:tt ... $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg) $modes +multiple $($tail)* }
|
||||
};
|
||||
// Shorthand magic
|
||||
// Shorthand magic
|
||||
(@arg ($arg:expr) $modes:tt #{$n:expr, $m:expr} $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg) $modes min_values($n) max_values($m) $($tail)* }
|
||||
};
|
||||
(@arg ($arg:expr) $modes:tt * $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg) $modes +required $($tail)* }
|
||||
};
|
||||
// !foo -> .foo(false)
|
||||
// !foo -> .foo(false)
|
||||
(@arg ($arg:expr) $modes:tt !$ident $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg.$ident(false)) $modes $($tail)* }
|
||||
};
|
||||
// foo -> .foo(true)
|
||||
// foo -> .foo(true)
|
||||
(@arg ($arg:expr) $modes:tt +$ident:ident $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg.$ident(true)) $modes $($tail)* }
|
||||
};
|
||||
// Validator
|
||||
// Validator
|
||||
(@arg ($arg:expr) $modes:tt {$fn_:expr} $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg.validator($fn_)) $modes $($tail)* }
|
||||
};
|
||||
(@as_expr $expr:expr) => { $expr };
|
||||
// Help
|
||||
// Help
|
||||
(@arg ($arg:expr) $modes:tt $desc:tt) => { $arg.help(clap_app!{ @as_expr $desc }) };
|
||||
// Handle functions that need to be called multiple times for each argument
|
||||
// Handle functions that need to be called multiple times for each argument
|
||||
(@arg ($arg:expr) $modes:tt $ident:ident[$($target:ident)*] $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg $( .$ident(stringify!($target)) )*) $modes $($tail)* }
|
||||
};
|
||||
// Inherit builder's functions
|
||||
// Inherit builder's functions
|
||||
(@arg ($arg:expr) $modes:tt $ident:ident($($expr:expr)*) $($tail:tt)*) => {
|
||||
clap_app!{ @arg ($arg.$ident($($expr)*)) $modes $($tail)* }
|
||||
};
|
||||
|
||||
// Build a subcommand outside of an app.
|
||||
// Build a subcommand outside of an app.
|
||||
(@subcommand $name:ident => $($tail:tt)*) => {
|
||||
clap_app!{ @app ($crate::SubCommand::with_name(stringify!($name))) $($tail)* }
|
||||
};
|
||||
// Start the magic
|
||||
// Start the magic
|
||||
($name:ident => $($tail:tt)*) => {{
|
||||
clap_app!{ @app ($crate::App::new(stringify!($name))) $($tail)*}
|
||||
}};
|
||||
|
|
|
@ -26,7 +26,7 @@ pub trait OsStrExt2 {
|
|||
#[cfg(target_os = "windows")]
|
||||
impl OsStrExt3 for OsStr {
|
||||
fn from_bytes(b: &[u8]) -> &Self {
|
||||
use ::std::mem;
|
||||
use std::mem;
|
||||
unsafe { mem::transmute(b) }
|
||||
}
|
||||
fn as_bytes(&self) -> &[u8] {
|
||||
|
@ -45,21 +45,28 @@ impl OsStrExt2 for OsStr {
|
|||
|
||||
fn contains_byte(&self, byte: u8) -> bool {
|
||||
for b in self.as_bytes() {
|
||||
if b == &byte { return true; }
|
||||
if b == &byte {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
fn split_at_byte(&self, byte: u8) -> (&OsStr, &OsStr) {
|
||||
for (i, b) in self.as_bytes().iter().enumerate() {
|
||||
if b == &byte { return (&OsStr::from_bytes(&self.as_bytes()[..i]), &OsStr::from_bytes(&self.as_bytes()[i+1..])); }
|
||||
if b == &byte {
|
||||
return (&OsStr::from_bytes(&self.as_bytes()[..i]),
|
||||
&OsStr::from_bytes(&self.as_bytes()[i + 1..]));
|
||||
}
|
||||
}
|
||||
(&*self, &OsStr::from_bytes(&self.as_bytes()[self.len_()..self.len_()]))
|
||||
}
|
||||
|
||||
fn trim_left_matches(&self, byte: u8) -> &OsStr {
|
||||
for (i, b) in self.as_bytes().iter().enumerate() {
|
||||
if b != &byte { return &OsStr::from_bytes(&self.as_bytes()[i..]); }
|
||||
if b != &byte {
|
||||
return &OsStr::from_bytes(&self.as_bytes()[i..]);
|
||||
}
|
||||
}
|
||||
&*self
|
||||
}
|
||||
|
@ -73,7 +80,11 @@ impl OsStrExt2 for OsStr {
|
|||
}
|
||||
|
||||
fn split(&self, b: u8) -> OsSplit {
|
||||
OsSplit { sep: b, val: self.as_bytes(), pos: 0 }
|
||||
OsSplit {
|
||||
sep: b,
|
||||
val: self.as_bytes(),
|
||||
pos: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -91,7 +102,9 @@ impl<'a> Iterator for OsSplit<'a> {
|
|||
fn next(&mut self) -> Option<&'a OsStr> {
|
||||
debugln!("fn=OsSplit::next;");
|
||||
debugln!("OsSplit: {:?}", self);
|
||||
if self.pos == self.val.len() { return None; }
|
||||
if self.pos == self.val.len() {
|
||||
return None;
|
||||
}
|
||||
let start = self.pos;
|
||||
for b in &self.val[start..] {
|
||||
self.pos += 1;
|
||||
|
@ -104,7 +117,9 @@ impl<'a> Iterator for OsSplit<'a> {
|
|||
fn size_hint(&self) -> (usize, Option<usize>) {
|
||||
let mut count = 0;
|
||||
for b in &self.val[self.pos..] {
|
||||
if *b == self.sep { count += 1; }
|
||||
if *b == self.sep {
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
if count > 0 {
|
||||
return (count, Some(count));
|
||||
|
@ -115,7 +130,9 @@ impl<'a> Iterator for OsSplit<'a> {
|
|||
|
||||
impl<'a> DoubleEndedIterator for OsSplit<'a> {
|
||||
fn next_back(&mut self) -> Option<&'a OsStr> {
|
||||
if self.pos == 0 { return None; }
|
||||
if self.pos == 0 {
|
||||
return None;
|
||||
}
|
||||
let start = self.pos;
|
||||
for b in self.val[..self.pos].iter().rev() {
|
||||
self.pos -= 1;
|
||||
|
|
|
@ -5,10 +5,12 @@ pub trait _StrExt {
|
|||
impl _StrExt for str {
|
||||
#[inline]
|
||||
fn _is_char_boundary(&self, index: usize) -> bool {
|
||||
if index == self.len() { return true; }
|
||||
if index == self.len() {
|
||||
return true;
|
||||
}
|
||||
match self.as_bytes().get(index) {
|
||||
None => false,
|
||||
Some(&b) => b < 128 || b >= 192,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,9 @@ pub fn did_you_mean<'a, T, I>(_: &str, _: I) -> Option<&'a str>
|
|||
/// Returns a suffix that can be empty, or is the standard 'did you mean phrase
|
||||
#[cfg_attr(feature = "lints", allow(needless_lifetimes))]
|
||||
pub fn did_you_mean_suffix<'z, T, I>(arg: &str,
|
||||
values: I,
|
||||
style: DidYouMeanMessageStyle)
|
||||
-> (String, Option<&'z str>)
|
||||
values: I,
|
||||
style: DidYouMeanMessageStyle)
|
||||
-> (String, Option<&'z str>)
|
||||
where T: AsRef<str> + 'z,
|
||||
I: IntoIterator<Item = &'z T>
|
||||
{
|
||||
|
@ -49,8 +49,9 @@ pub fn did_you_mean_suffix<'z, T, I>(arg: &str,
|
|||
Some(candidate) => {
|
||||
let mut suffix = "\n\tDid you mean ".to_owned();
|
||||
match style {
|
||||
DidYouMeanMessageStyle::LongFlag =>
|
||||
suffix.push_str(&Format::Good("--").to_string()),
|
||||
DidYouMeanMessageStyle::LongFlag => {
|
||||
suffix.push_str(&Format::Good("--").to_string())
|
||||
}
|
||||
DidYouMeanMessageStyle::EnumValue => suffix.push('\''),
|
||||
}
|
||||
suffix.push_str(&Format::Good(candidate).to_string()[..]);
|
||||
|
@ -92,13 +93,15 @@ mod test {
|
|||
fn suffix_long() {
|
||||
let p_vals = ["test", "possible", "values"];
|
||||
let suffix = "\n\tDid you mean \'--test\' ?";
|
||||
assert_eq!(did_you_mean_suffix("tst", p_vals.iter(), DidYouMeanMessageStyle::LongFlag), (suffix, Some("test")));
|
||||
assert_eq!(did_you_mean_suffix("tst", p_vals.iter(), DidYouMeanMessageStyle::LongFlag),
|
||||
(suffix, Some("test")));
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn suffix_enum() {
|
||||
let p_vals = ["test", "possible", "values"];
|
||||
let suffix = "\n\tDid you mean \'test\' ?";
|
||||
assert_eq!(did_you_mean_suffix("tst", p_vals.iter(), DidYouMeanMessageStyle::EnumValue), (suffix, Some("test")));
|
||||
assert_eq!(did_you_mean_suffix("tst", p_vals.iter(), DidYouMeanMessageStyle::EnumValue),
|
||||
(suffix, Some("test")));
|
||||
}
|
||||
}
|
||||
|
|
10
src/term.rs
10
src/term.rs
|
@ -15,7 +15,7 @@
|
|||
#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
|
||||
use std::mem::zeroed;
|
||||
#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
|
||||
use libc::{c_int, c_ushort, c_ulong, STDOUT_FILENO};
|
||||
use libc::{STDOUT_FILENO, c_int, c_ulong, c_ushort};
|
||||
|
||||
|
||||
/// The number of rows and columns of a terminal.
|
||||
|
@ -41,7 +41,7 @@ static TIOCGWINSZ: c_ulong = 0x5413;
|
|||
#[cfg(feature = "wrap_help")]
|
||||
static TIOCGWINSZ: c_ulong = 0x40087468;
|
||||
|
||||
extern {
|
||||
extern "C" {
|
||||
#[cfg(all(feature = "wrap_help", not(target_os = "windows")))]
|
||||
pub fn ioctl(fd: c_int, request: c_ulong, ...) -> c_int;
|
||||
}
|
||||
|
@ -56,8 +56,7 @@ unsafe fn get_dimensions() -> Winsize {
|
|||
|
||||
if result == -1 {
|
||||
zeroed()
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
window
|
||||
}
|
||||
}
|
||||
|
@ -70,8 +69,7 @@ pub fn dimensions() -> Option<(usize, usize)> {
|
|||
|
||||
if w.ws_col == 0 || w.ws_row == 0 {
|
||||
None
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
Some((w.ws_col as usize, w.ws_row as usize))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,7 +14,7 @@ enum UsageToken {
|
|||
Long,
|
||||
Help,
|
||||
Multiple,
|
||||
Unknown
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
@ -24,7 +24,7 @@ pub struct UsageParser<'a> {
|
|||
pos: usize,
|
||||
start: usize,
|
||||
prev: UsageToken,
|
||||
explicit_name_set: bool
|
||||
explicit_name_set: bool,
|
||||
}
|
||||
|
||||
impl<'a> UsageParser<'a> {
|
||||
|
@ -53,16 +53,24 @@ impl<'a> UsageParser<'a> {
|
|||
if self.pos < self.usage.len() {
|
||||
if let Some(c) = self.usage.chars().nth(self.pos) {
|
||||
match c {
|
||||
'-' => self.short_or_long(&mut arg),
|
||||
'.' => self.multiple(&mut arg),
|
||||
'-' => self.short_or_long(&mut arg),
|
||||
'.' => self.multiple(&mut arg),
|
||||
'\'' => self.help(&mut arg),
|
||||
_ => self.name(&mut arg),
|
||||
_ => self.name(&mut arg),
|
||||
}
|
||||
}
|
||||
} else { break; }
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
debug_assert!(!arg.name.is_empty(), format!("No name found for Arg when parsing usage string: {}", self.usage));
|
||||
let n_vals = if let Some(ref v) = arg.val_names { v.len() } else { 0 };
|
||||
debug_assert!(!arg.name.is_empty(),
|
||||
format!("No name found for Arg when parsing usage string: {}",
|
||||
self.usage));
|
||||
let n_vals = if let Some(ref v) = arg.val_names {
|
||||
v.len()
|
||||
} else {
|
||||
0
|
||||
};
|
||||
if n_vals > 1 {
|
||||
arg.num_vals = Some(n_vals as u64);
|
||||
}
|
||||
|
@ -72,7 +80,10 @@ impl<'a> UsageParser<'a> {
|
|||
|
||||
fn name(&mut self, arg: &mut Arg<'a, 'a>) {
|
||||
debugln!("fn=name;");
|
||||
if self.usage.chars().nth(self.pos).expect(INTERNAL_ERROR_MSG) == '<' && !self.explicit_name_set { arg.setb(ArgSettings::Required); }
|
||||
if self.usage.chars().nth(self.pos).expect(INTERNAL_ERROR_MSG) == '<' &&
|
||||
!self.explicit_name_set {
|
||||
arg.setb(ArgSettings::Required);
|
||||
}
|
||||
self.pos += 1;
|
||||
self.stop_at(name_end);
|
||||
let name = &self.usage[self.start..self.pos];
|
||||
|
@ -99,11 +110,16 @@ impl<'a> UsageParser<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
fn stop_at<F>(&mut self, f: F) where F: Fn(u32) -> bool {
|
||||
fn stop_at<F>(&mut self, f: F)
|
||||
where F: Fn(u32) -> bool
|
||||
{
|
||||
debugln!("fn=stop_at;");
|
||||
self.start = self.pos;
|
||||
for c in self.usage[self.start..].chars() {
|
||||
if f(c as u32) { self.pos += 1; continue; }
|
||||
if f(c as u32) {
|
||||
self.pos += 1;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -157,10 +173,10 @@ impl<'a> UsageParser<'a> {
|
|||
debugln!("setting multiple");
|
||||
arg.setb(ArgSettings::Multiple);
|
||||
self.prev = UsageToken::Multiple;
|
||||
self.pos += 1;
|
||||
self.pos += 1;
|
||||
break;
|
||||
}
|
||||
},
|
||||
}
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
|
@ -169,8 +185,8 @@ impl<'a> UsageParser<'a> {
|
|||
fn help(&mut self, arg: &mut Arg<'a, 'a>) {
|
||||
debugln!("fn=help;");
|
||||
self.stop_at(help_start);
|
||||
self.start = self.pos+1;
|
||||
self.pos = self.usage.len()-1;
|
||||
self.start = self.pos + 1;
|
||||
self.pos = self.usage.len() - 1;
|
||||
debugln!("setting help: {}", &self.usage[self.start..self.pos]);
|
||||
arg.help = Some(&self.usage[self.start..self.pos]);
|
||||
self.pos += 1; // Move to next byte to keep from thinking ending ' is a start
|
||||
|
@ -193,7 +209,8 @@ fn token(b: u32) -> bool {
|
|||
#[inline]
|
||||
fn long_end(b: u32) -> bool {
|
||||
// 39('), 46(.), 60(<), 61(=), 91([)
|
||||
(b < 39 && (b > 13 && b != b' ' as u32)) || b > 91 || (b > 61 && b < 91) || (b > 39 && b < 60 && b != 46)
|
||||
(b < 39 && (b > 13 && b != b' ' as u32)) || b > 91 || (b > 61 && b < 91) ||
|
||||
(b > 39 && b < 60 && b != 46)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -332,7 +349,8 @@ mod test {
|
|||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -346,7 +364,8 @@ mod test {
|
|||
assert!(!b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -360,7 +379,8 @@ mod test {
|
|||
assert!(!c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -374,7 +394,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -388,7 +409,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -402,7 +424,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -416,7 +439,8 @@ mod test {
|
|||
assert!(b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -430,7 +454,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -444,7 +469,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -458,7 +484,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -472,7 +499,8 @@ mod test {
|
|||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -486,7 +514,8 @@ mod test {
|
|||
assert!(!b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -500,7 +529,8 @@ mod test {
|
|||
assert!(!c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -514,7 +544,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -528,7 +559,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -542,7 +574,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -556,7 +589,8 @@ mod test {
|
|||
assert!(b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -570,7 +604,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -584,7 +619,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -598,7 +634,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -612,7 +649,8 @@ mod test {
|
|||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -626,7 +664,8 @@ mod test {
|
|||
assert!(!b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -640,7 +679,8 @@ mod test {
|
|||
assert!(!c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -654,7 +694,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -668,7 +709,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -682,7 +724,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -696,7 +739,8 @@ mod test {
|
|||
assert!(b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -710,7 +754,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -724,7 +769,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -738,7 +784,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -752,7 +799,8 @@ mod test {
|
|||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -766,7 +814,8 @@ mod test {
|
|||
assert!(!b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -780,7 +829,8 @@ mod test {
|
|||
assert!(!c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -794,7 +844,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -808,7 +859,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -822,7 +874,8 @@ mod test {
|
|||
assert!(b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -836,7 +889,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -850,7 +904,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -864,7 +919,8 @@ mod test {
|
|||
assert!(!a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -878,7 +934,8 @@ mod test {
|
|||
assert!(!b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -892,7 +949,8 @@ mod test {
|
|||
assert!(!c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -906,7 +964,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -920,7 +979,8 @@ mod test {
|
|||
assert!(a.is_set(ArgSettings::Multiple));
|
||||
assert!(a.is_set(ArgSettings::TakesValue));
|
||||
assert!(!a.is_set(ArgSettings::Required));
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(a.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(a.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -934,7 +994,8 @@ mod test {
|
|||
assert!(b.is_set(ArgSettings::Multiple));
|
||||
assert!(b.is_set(ArgSettings::TakesValue));
|
||||
assert!(!b.is_set(ArgSettings::Required));
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(b.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(b.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -948,7 +1009,8 @@ mod test {
|
|||
assert!(c.is_set(ArgSettings::Multiple));
|
||||
assert!(c.is_set(ArgSettings::TakesValue));
|
||||
assert!(c.is_set(ArgSettings::Required));
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["opt"]);
|
||||
assert_eq!(c.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["opt"]);
|
||||
assert!(c.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -962,7 +1024,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["option"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["option"]);
|
||||
assert!(d.num_vals.is_none());
|
||||
}
|
||||
|
||||
|
@ -976,7 +1039,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["file", "mode"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["file", "mode"]);
|
||||
assert_eq!(d.num_vals.unwrap(), 2);
|
||||
}
|
||||
|
||||
|
@ -990,7 +1054,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["file", "mode"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["file", "mode"]);
|
||||
assert_eq!(d.num_vals.unwrap(), 2);
|
||||
}
|
||||
|
||||
|
@ -1004,7 +1069,8 @@ mod test {
|
|||
assert!(d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["file", "mode"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["file", "mode"]);
|
||||
assert_eq!(d.num_vals.unwrap(), 2);
|
||||
}
|
||||
|
||||
|
@ -1018,7 +1084,8 @@ mod test {
|
|||
assert!(!d.is_set(ArgSettings::Multiple));
|
||||
assert!(d.is_set(ArgSettings::TakesValue));
|
||||
assert!(!d.is_set(ArgSettings::Required));
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(), ["file", "mode"]);
|
||||
assert_eq!(d.val_names.unwrap().iter().map(|(_, &v)| v).collect::<Vec<_>>(),
|
||||
["file", "mode"]);
|
||||
assert_eq!(d.num_vals.unwrap(), 2);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue