feat(from_usage): adds ability to add value names or num of vals in usage string

Allows new usage strings with value names or number of values. If the
names are consecutive, they are counted to represent the number of
values (if they all have the same name), or if their names are different
they are used as value names.

Closes #98
This commit is contained in:
Kevin K 2015-05-04 23:36:45 -04:00
parent be77f0c5cf
commit 3d58197674
2 changed files with 249 additions and 16 deletions

View file

@ -1,4 +1,5 @@
use std::iter::IntoIterator; use std::iter::IntoIterator;
use std::collections::HashSet;
use usageparser::{UsageParser, UsageToken}; use usageparser::{UsageParser, UsageToken};
@ -79,7 +80,7 @@ pub struct Arg<'n, 'l, 'h, 'g, 'p, 'r> {
#[doc(hidden)] #[doc(hidden)]
pub group: Option<&'g str>, pub group: Option<&'g str>,
#[doc(hidden)] #[doc(hidden)]
pub val_names: Option<Vec<&'p str>>, pub val_names: Option<Vec<&'n str>>,
#[doc(hidden)] #[doc(hidden)]
pub num_vals: Option<u8>, pub num_vals: Option<u8>,
#[doc(hidden)] #[doc(hidden)]
@ -229,34 +230,57 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
let mut required = false; let mut required = false;
let mut takes_value = false; let mut takes_value = false;
let mut multiple = false; let mut multiple = false;
let mut num_names = 1;
let mut name_first = false;
let mut consec_names = false;
let mut val_names = HashSet::new();
let parser = UsageParser::with_usage(u); let parser = UsageParser::with_usage(u);
for_match!{ parser, for_match!{ parser,
UsageToken::Name(n, req) => { UsageToken::Name(n, req) => {
if name.is_none() { if consec_names {
num_names += 1;
}
let mut use_req = false;
let mut use_name = false;
if name.is_none() && long.is_none() && short.is_none() {
name_first = true;
use_name = true;
use_req = true;
} else if let Some(l) = long {
if l == name.unwrap_or("") {
if !name_first {
use_name = true;
use_req = true;
}
}
} else {
// starting with short
if !name_first {
use_name = true;
use_req = true;
}
}
if use_name && !consec_names {
name = Some(n); name = Some(n);
}
if use_req && !consec_names {
if let Some(r) = req { if let Some(r) = req {
required = r; required = r;
} }
} else if let Some(l) = long {
if l == name.unwrap() {
if let Some(r) = req {
required = r;
}
name = Some(n);
} else if n != l {
name = Some(n);
}
} }
if short.is_some() || long.is_some() { if short.is_some() || long.is_some() {
val_names.insert(n);
takes_value = true; takes_value = true;
} }
consec_names = true;
}, },
UsageToken::Short(s) => { UsageToken::Short(s) => {
consec_names = false;
short = Some(s); short = Some(s);
}, },
UsageToken::Long(l) => { UsageToken::Long(l) => {
consec_names = false;
long = Some(l); long = Some(l);
if name.is_none() { if name.is_none() {
name = Some(l); name = Some(l);
@ -270,6 +294,15 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
} }
} }
if let Some(l) = long {
val_names.remove(l);
if val_names.len() > 1 {
if name.unwrap() != l && !name_first {
name = Some(l);
}
}
}
Arg { Arg {
name: name.unwrap(), name: name.unwrap(),
short: short, short: short,
@ -282,8 +315,8 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
possible_vals: None, possible_vals: None,
blacklist: None, blacklist: None,
requires: None, requires: None,
num_vals: None, num_vals: if num_names > 1 { Some(num_names) } else { None },
val_names: None, val_names: if val_names.len() > 1 {Some(val_names.iter().map(|s| *s).collect::<Vec<_>>())}else{None},
max_vals: None, max_vals: None,
min_vals: None, min_vals: None,
group: None, group: None,
@ -765,8 +798,8 @@ impl<'n, 'l, 'h, 'g, 'p, 'r> Arg<'n, 'l, 'h, 'g, 'p, 'r> {
/// # ).get_matches(); /// # ).get_matches();
pub fn value_names<T, I>(mut self, names: I) pub fn value_names<T, I>(mut self, names: I)
-> Arg<'n, 'l, 'h, 'g, 'p, 'r> -> Arg<'n, 'l, 'h, 'g, 'p, 'r>
where T: AsRef<str> + 'p, where T: AsRef<str> + 'n,
I: IntoIterator<Item=&'p T> { I: IntoIterator<Item=&'n T> {
if let Some(ref mut vec) = self.val_names { if let Some(ref mut vec) = self.val_names {
names.into_iter().map(|s| vec.push(s.as_ref())).collect::<Vec<_>>(); names.into_iter().map(|s| vec.push(s.as_ref())).collect::<Vec<_>>();
} else { } else {

View file

@ -361,6 +361,7 @@ mod usageparser;
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::{App, Arg, SubCommand}; use super::{App, Arg, SubCommand};
use std::collections::HashSet;
#[test] #[test]
fn create_app() { fn create_app() {
@ -394,6 +395,8 @@ mod tests {
assert!(a.long.is_none()); assert!(a.long.is_none());
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.multiple); assert!(!a.multiple);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("[flag] --flag 'some help info'"); let b = Arg::from_usage("[flag] --flag 'some help info'");
assert_eq!(b.name, "flag"); assert_eq!(b.name, "flag");
@ -401,6 +404,8 @@ mod tests {
assert!(b.short.is_none()); assert!(b.short.is_none());
assert_eq!(b.help.unwrap(), "some help info"); assert_eq!(b.help.unwrap(), "some help info");
assert!(!b.multiple); assert!(!b.multiple);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("--flag 'some help info'"); let b = Arg::from_usage("--flag 'some help info'");
assert_eq!(b.name, "flag"); assert_eq!(b.name, "flag");
@ -408,6 +413,8 @@ mod tests {
assert!(b.short.is_none()); assert!(b.short.is_none());
assert_eq!(b.help.unwrap(), "some help info"); assert_eq!(b.help.unwrap(), "some help info");
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("[flag] -f --flag 'some help info'"); let c = Arg::from_usage("[flag] -f --flag 'some help info'");
assert_eq!(c.name, "flag"); assert_eq!(c.name, "flag");
@ -415,6 +422,8 @@ mod tests {
assert_eq!(c.long.unwrap(), "flag"); assert_eq!(c.long.unwrap(), "flag");
assert_eq!(c.help.unwrap(), "some help info"); assert_eq!(c.help.unwrap(), "some help info");
assert!(!c.multiple); assert!(!c.multiple);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("[flag] -f... 'some help info'"); let d = Arg::from_usage("[flag] -f... 'some help info'");
assert_eq!(d.name, "flag"); assert_eq!(d.name, "flag");
@ -422,6 +431,8 @@ mod tests {
assert!(d.long.is_none()); assert!(d.long.is_none());
assert_eq!(d.help.unwrap(), "some help info"); assert_eq!(d.help.unwrap(), "some help info");
assert!(d.multiple); assert!(d.multiple);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let e = Arg::from_usage("[flag] -f --flag... 'some help info'"); let e = Arg::from_usage("[flag] -f --flag... 'some help info'");
assert_eq!(e.name, "flag"); assert_eq!(e.name, "flag");
@ -429,6 +440,8 @@ mod tests {
assert_eq!(e.short.unwrap(), 'f'); assert_eq!(e.short.unwrap(), 'f');
assert_eq!(e.help.unwrap(), "some help info"); assert_eq!(e.help.unwrap(), "some help info");
assert!(e.multiple); assert!(e.multiple);
assert!(e.val_names.is_none());
assert!(e.num_vals.is_none());
let e = Arg::from_usage("-f --flag... 'some help info'"); let e = Arg::from_usage("-f --flag... 'some help info'");
assert_eq!(e.name, "flag"); assert_eq!(e.name, "flag");
@ -436,24 +449,34 @@ mod tests {
assert_eq!(e.short.unwrap(), 'f'); assert_eq!(e.short.unwrap(), 'f');
assert_eq!(e.help.unwrap(), "some help info"); assert_eq!(e.help.unwrap(), "some help info");
assert!(e.multiple); assert!(e.multiple);
assert!(e.val_names.is_none());
assert!(e.num_vals.is_none());
let e = Arg::from_usage("--flags"); let e = Arg::from_usage("--flags");
assert_eq!(e.name, "flags"); assert_eq!(e.name, "flags");
assert_eq!(e.long.unwrap(), "flags"); assert_eq!(e.long.unwrap(), "flags");
assert!(e.val_names.is_none());
assert!(e.num_vals.is_none());
let e = Arg::from_usage("--flags..."); let e = Arg::from_usage("--flags...");
assert_eq!(e.name, "flags"); assert_eq!(e.name, "flags");
assert_eq!(e.long.unwrap(), "flags"); assert_eq!(e.long.unwrap(), "flags");
assert!(e.multiple); assert!(e.multiple);
assert!(e.val_names.is_none());
assert!(e.num_vals.is_none());
let e = Arg::from_usage("[flags] -f"); let e = Arg::from_usage("[flags] -f");
assert_eq!(e.name, "flags"); assert_eq!(e.name, "flags");
assert_eq!(e.short.unwrap(), 'f'); assert_eq!(e.short.unwrap(), 'f');
assert!(e.val_names.is_none());
assert!(e.num_vals.is_none());
let e = Arg::from_usage("[flags] -f..."); let e = Arg::from_usage("[flags] -f...");
assert_eq!(e.name, "flags"); assert_eq!(e.name, "flags");
assert_eq!(e.short.unwrap(), 'f'); assert_eq!(e.short.unwrap(), 'f');
assert!(e.multiple); assert!(e.multiple);
assert!(e.val_names.is_none());
assert!(e.num_vals.is_none());
} }
#[test] #[test]
@ -472,34 +495,46 @@ mod tests {
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.multiple); assert!(!a.multiple);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("<pos> 'some help info'"); let b = Arg::from_usage("<pos> 'some help info'");
assert_eq!(b.name, "pos"); assert_eq!(b.name, "pos");
assert_eq!(b.help.unwrap(), "some help info"); assert_eq!(b.help.unwrap(), "some help info");
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.required); assert!(b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("[pos]... 'some help info'"); let c = Arg::from_usage("[pos]... 'some help info'");
assert_eq!(c.name, "pos"); assert_eq!(c.name, "pos");
assert_eq!(c.help.unwrap(), "some help info"); assert_eq!(c.help.unwrap(), "some help info");
assert!(c.multiple); assert!(c.multiple);
assert!(!c.required); assert!(!c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("<pos>... 'some help info'"); let d = Arg::from_usage("<pos>... 'some help info'");
assert_eq!(d.name, "pos"); assert_eq!(d.name, "pos");
assert_eq!(d.help.unwrap(), "some help info"); assert_eq!(d.help.unwrap(), "some help info");
assert!(d.multiple); assert!(d.multiple);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let b = Arg::from_usage("<pos>"); let b = Arg::from_usage("<pos>");
assert_eq!(b.name, "pos"); assert_eq!(b.name, "pos");
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.required); assert!(b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("[pos]..."); let c = Arg::from_usage("[pos]...");
assert_eq!(c.name, "pos"); assert_eq!(c.name, "pos");
assert!(c.multiple); assert!(c.multiple);
assert!(!c.required); assert!(!c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
} }
#[test] #[test]
@ -509,24 +544,32 @@ mod tests {
assert_eq!(a.help.unwrap(), "some help info"); assert_eq!(a.help.unwrap(), "some help info");
assert!(!a.multiple); assert!(!a.multiple);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("<pos>\t'some help info'"); let b = Arg::from_usage("<pos>\t'some help info'");
assert_eq!(b.name, "pos"); assert_eq!(b.name, "pos");
assert_eq!(b.help.unwrap(), "some help info"); assert_eq!(b.help.unwrap(), "some help info");
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.required); assert!(b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("[pos]...\t'some help info'"); let c = Arg::from_usage("[pos]...\t'some help info'");
assert_eq!(c.name, "pos"); assert_eq!(c.name, "pos");
assert_eq!(c.help.unwrap(), "some help info"); assert_eq!(c.help.unwrap(), "some help info");
assert!(c.multiple); assert!(c.multiple);
assert!(!c.required); assert!(!c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("<pos>...\t'some help info'"); let d = Arg::from_usage("<pos>...\t'some help info'");
assert_eq!(d.name, "pos"); assert_eq!(d.name, "pos");
assert_eq!(d.help.unwrap(), "some help info"); assert_eq!(d.help.unwrap(), "some help info");
assert!(d.multiple); assert!(d.multiple);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
} }
#[test] #[test]
@ -551,6 +594,8 @@ mod tests {
assert!(!a.multiple); assert!(!a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("-o [opt] 'some help info'"); let b = Arg::from_usage("-o [opt] 'some help info'");
assert_eq!(b.name, "opt"); assert_eq!(b.name, "opt");
@ -560,6 +605,8 @@ mod tests {
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> -o <opt> 'some help info'"); let c = Arg::from_usage("<option> -o <opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -569,6 +616,8 @@ mod tests {
assert!(!c.multiple); assert!(!c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("-o <opt> 'some help info'"); let d = Arg::from_usage("-o <opt> 'some help info'");
assert_eq!(d.name, "opt"); assert_eq!(d.name, "opt");
@ -578,6 +627,8 @@ mod tests {
assert!(!d.multiple); assert!(!d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let a = Arg::from_usage("[option] -o [opt]... 'some help info'"); let a = Arg::from_usage("[option] -o [opt]... 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -587,6 +638,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let a = Arg::from_usage("[option]... -o [opt] 'some help info'"); let a = Arg::from_usage("[option]... -o [opt] 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -596,6 +649,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("-o [opt]... 'some help info'"); let b = Arg::from_usage("-o [opt]... 'some help info'");
assert_eq!(b.name, "opt"); assert_eq!(b.name, "opt");
@ -605,6 +660,8 @@ mod tests {
assert!(b.multiple); assert!(b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> -o <opt>... 'some help info'"); let c = Arg::from_usage("<option> -o <opt>... 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -614,6 +671,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let c = Arg::from_usage("<option>... -o <opt> 'some help info'"); let c = Arg::from_usage("<option>... -o <opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -623,6 +682,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("-o <opt>... 'some help info'"); let d = Arg::from_usage("-o <opt>... 'some help info'");
assert_eq!(d.name, "opt"); assert_eq!(d.name, "opt");
@ -632,6 +693,8 @@ mod tests {
assert!(d.multiple); assert!(d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
// Long only // Long only
@ -643,6 +706,8 @@ mod tests {
assert!(!a.multiple); assert!(!a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("--opt [option] 'some help info'"); let b = Arg::from_usage("--opt [option] 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -652,6 +717,8 @@ mod tests {
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> --opt <opt> 'some help info'"); let c = Arg::from_usage("<option> --opt <opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -661,6 +728,8 @@ mod tests {
assert!(!c.multiple); assert!(!c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("--opt <option> 'some help info'"); let d = Arg::from_usage("--opt <option> 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -670,6 +739,8 @@ mod tests {
assert!(!d.multiple); assert!(!d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let a = Arg::from_usage("[option] --opt [opt]... 'some help info'"); let a = Arg::from_usage("[option] --opt [opt]... 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -679,6 +750,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let a = Arg::from_usage("[option]... --opt [opt] 'some help info'"); let a = Arg::from_usage("[option]... --opt [opt] 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -688,6 +761,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("--opt [option]... 'some help info'"); let b = Arg::from_usage("--opt [option]... 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -697,6 +772,8 @@ mod tests {
assert!(b.multiple); assert!(b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> --opt <opt>... 'some help info'"); let c = Arg::from_usage("<option> --opt <opt>... 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -706,6 +783,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let c = Arg::from_usage("<option>... --opt <opt> 'some help info'"); let c = Arg::from_usage("<option>... --opt <opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -715,6 +794,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("--opt <option>... 'some help info'"); let d = Arg::from_usage("--opt <option>... 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -724,6 +805,8 @@ mod tests {
assert!(d.multiple); assert!(d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
// Long only with '=' // Long only with '='
@ -735,6 +818,8 @@ mod tests {
assert!(!a.multiple); assert!(!a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("--opt=[option] 'some help info'"); let b = Arg::from_usage("--opt=[option] 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -744,6 +829,8 @@ mod tests {
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> --opt=<opt> 'some help info'"); let c = Arg::from_usage("<option> --opt=<opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -753,6 +840,8 @@ mod tests {
assert!(!c.multiple); assert!(!c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("--opt=<option> 'some help info'"); let d = Arg::from_usage("--opt=<option> 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -762,6 +851,8 @@ mod tests {
assert!(!d.multiple); assert!(!d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let a = Arg::from_usage("[option] --opt=[opt]... 'some help info'"); let a = Arg::from_usage("[option] --opt=[opt]... 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -771,6 +862,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let a = Arg::from_usage("[option]... --opt=[opt] 'some help info'"); let a = Arg::from_usage("[option]... --opt=[opt] 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -780,6 +873,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("--opt=[option]... 'some help info'"); let b = Arg::from_usage("--opt=[option]... 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -789,6 +884,8 @@ mod tests {
assert!(b.multiple); assert!(b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> --opt=<opt>... 'some help info'"); let c = Arg::from_usage("<option> --opt=<opt>... 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -798,6 +895,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let c = Arg::from_usage("<option>... --opt=<opt> 'some help info'"); let c = Arg::from_usage("<option>... --opt=<opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -807,6 +906,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("--opt=<option>... 'some help info'"); let d = Arg::from_usage("--opt=<option>... 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -816,6 +917,8 @@ mod tests {
assert!(d.multiple); assert!(d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
// Long and Short // Long and Short
@ -827,6 +930,8 @@ mod tests {
assert!(!a.multiple); assert!(!a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("-o --opt [option] 'some help info'"); let b = Arg::from_usage("-o --opt [option] 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -836,6 +941,8 @@ mod tests {
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> -o --opt <opt> 'some help info'"); let c = Arg::from_usage("<option> -o --opt <opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -845,6 +952,8 @@ mod tests {
assert!(!c.multiple); assert!(!c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("-o --opt <option> 'some help info'"); let d = Arg::from_usage("-o --opt <option> 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -854,6 +963,8 @@ mod tests {
assert!(!d.multiple); assert!(!d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let a = Arg::from_usage("[option]... -o --opt [option] 'some help info'"); let a = Arg::from_usage("[option]... -o --opt [option] 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -863,6 +974,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("-o --opt [option]... 'some help info'"); let b = Arg::from_usage("-o --opt [option]... 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -872,6 +985,8 @@ mod tests {
assert!(b.multiple); assert!(b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option>... -o --opt <opt> 'some help info'"); let c = Arg::from_usage("<option>... -o --opt <opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -881,6 +996,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("-o --opt <option>... 'some help info'"); let d = Arg::from_usage("-o --opt <option>... 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -890,6 +1007,8 @@ mod tests {
assert!(d.multiple); assert!(d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
// Long and Short with '=' // Long and Short with '='
@ -901,6 +1020,8 @@ mod tests {
assert!(!a.multiple); assert!(!a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("-o --opt=[option] 'some help info'"); let b = Arg::from_usage("-o --opt=[option] 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -910,6 +1031,8 @@ mod tests {
assert!(!b.multiple); assert!(!b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option> -o --opt=<opt> 'some help info'"); let c = Arg::from_usage("<option> -o --opt=<opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -919,6 +1042,8 @@ mod tests {
assert!(!c.multiple); assert!(!c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("-o --opt=<option> 'some help info'"); let d = Arg::from_usage("-o --opt=<option> 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -928,6 +1053,8 @@ mod tests {
assert!(!d.multiple); assert!(!d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
let a = Arg::from_usage("[option]... -o --opt=[option] 'some help info'"); let a = Arg::from_usage("[option]... -o --opt=[option] 'some help info'");
assert_eq!(a.name, "option"); assert_eq!(a.name, "option");
@ -937,6 +1064,8 @@ mod tests {
assert!(a.multiple); assert!(a.multiple);
assert!(a.takes_value); assert!(a.takes_value);
assert!(!a.required); assert!(!a.required);
assert!(a.val_names.is_none());
assert!(a.num_vals.is_none());
let b = Arg::from_usage("-o --opt=[option]... 'some help info'"); let b = Arg::from_usage("-o --opt=[option]... 'some help info'");
assert_eq!(b.name, "option"); assert_eq!(b.name, "option");
@ -946,6 +1075,8 @@ mod tests {
assert!(b.multiple); assert!(b.multiple);
assert!(b.takes_value); assert!(b.takes_value);
assert!(!b.required); assert!(!b.required);
assert!(b.val_names.is_none());
assert!(b.num_vals.is_none());
let c = Arg::from_usage("<option>... -o --opt=<opt> 'some help info'"); let c = Arg::from_usage("<option>... -o --opt=<opt> 'some help info'");
assert_eq!(c.name, "option"); assert_eq!(c.name, "option");
@ -955,6 +1086,8 @@ mod tests {
assert!(c.multiple); assert!(c.multiple);
assert!(c.takes_value); assert!(c.takes_value);
assert!(c.required); assert!(c.required);
assert!(c.val_names.is_none());
assert!(c.num_vals.is_none());
let d = Arg::from_usage("-o --opt=<option>... 'some help info'"); let d = Arg::from_usage("-o --opt=<option>... 'some help info'");
assert_eq!(d.name, "option"); assert_eq!(d.name, "option");
@ -964,6 +1097,73 @@ mod tests {
assert!(d.multiple); assert!(d.multiple);
assert!(d.takes_value); assert!(d.takes_value);
assert!(d.required); assert!(d.required);
assert!(d.val_names.is_none());
assert!(d.num_vals.is_none());
}
#[test]
fn create_option_with_vals() {
let d = Arg::from_usage("-o <opt> <opt> 'some help info'");
assert_eq!(d.name, "opt");
assert!(d.long.is_none());
assert_eq!(d.short.unwrap(), 'o');
assert_eq!(d.help.unwrap(), "some help info");
assert!(!d.multiple);
assert!(d.takes_value);
assert!(d.required);
assert!(d.val_names.is_none());
assert_eq!(d.num_vals.unwrap(), 2);
let d = Arg::from_usage("-o <opt> <opt>... 'some help info'");
assert_eq!(d.name, "opt");
assert!(d.long.is_none());
assert_eq!(d.short.unwrap(), 'o');
assert_eq!(d.help.unwrap(), "some help info");
assert!(d.multiple);
assert!(d.takes_value);
assert!(d.required);
assert!(d.val_names.is_none());
assert_eq!(d.num_vals.unwrap(), 2);
let d = Arg::from_usage("--opt <file> <mode>... 'some help info'");
assert_eq!(d.name, "opt");
assert!(d.short.is_none());
assert_eq!(d.long.unwrap(), "opt");
assert_eq!(d.help.unwrap(), "some help info");
assert!(d.multiple);
assert!(d.takes_value);
assert!(d.required);
let mut v = d.val_names.unwrap().into_iter().collect::<HashSet<_>>();
for name in &["mode", "file"] {
assert!(v.remove(name));
}
assert!(v.is_empty());
assert_eq!(d.num_vals.unwrap(), 2);
let d = Arg::from_usage("[myopt] --opt <file> <mode> 'some help info'");
assert_eq!(d.name, "myopt");
assert!(d.short.is_none());
assert_eq!(d.long.unwrap(), "opt");
assert_eq!(d.help.unwrap(), "some help info");
assert!(!d.multiple);
assert!(d.takes_value);
assert!(!d.required);
let mut v = d.val_names.unwrap().into_iter().collect::<HashSet<_>>();
for name in &["mode", "file"] {
assert!(v.remove(name));
}
assert!(v.is_empty());
assert_eq!(d.num_vals.unwrap(), 2);
let d = Arg::from_usage("--opt <option> <option> 'some help info'");
assert_eq!(d.name, "option");
assert!(d.short.is_none());
assert_eq!(d.long.unwrap(), "opt");
assert_eq!(d.help.unwrap(), "some help info");
assert!(!d.multiple);
assert!(d.takes_value);
assert!(d.required);
assert_eq!(d.num_vals.unwrap(), 2);
} }
#[test] #[test]