mirror of
https://github.com/clap-rs/clap
synced 2024-12-13 06:12:40 +00:00
feat(args): add support for a specific set of allowed values on options
or positional arguments
This commit is contained in:
parent
bcd1fa728e
commit
270eb88925
5 changed files with 202 additions and 47 deletions
159
src/app.rs
159
src/app.rs
|
@ -180,7 +180,7 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
/// )
|
||||
/// # .get_matches();
|
||||
/// ```
|
||||
pub fn arg<'l, 'h, 'b, 'r>(mut self, a: Arg<'ar, 'ar, 'ar, 'ar, 'ar>) -> App<'a, 'v, 'ab, 'u, 'ar> {
|
||||
pub fn arg<'l, 'h, 'b, 'r>(mut self, a: Arg<'ar, 'ar, 'ar, 'ar, 'ar, 'ar>) -> App<'a, 'v, 'ab, 'u, 'ar> {
|
||||
if self.arg_list.contains(a.name) {
|
||||
panic!("Argument name must be unique, \"{}\" is already in use", a.name);
|
||||
} else {
|
||||
|
@ -213,30 +213,76 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
if a.takes_value {
|
||||
panic!("Argument \"{}\" has conflicting requirements, both index() and takes_value(true) were supplied", a.name);
|
||||
}
|
||||
self.positionals_idx.insert(i, PosBuilder {
|
||||
// Create the Positional Arguemnt Builder with each HashSet = None to only allocate those that require it
|
||||
let mut pb = PosBuilder {
|
||||
name: a.name,
|
||||
index: i,
|
||||
required: a.required,
|
||||
blacklist: a.blacklist,
|
||||
requires: a.requires,
|
||||
blacklist: None,
|
||||
requires: None,
|
||||
possible_vals: None,
|
||||
help: a.help,
|
||||
});
|
||||
};
|
||||
// Check if there is anything in the blacklist (mutually excludes list) and add any values
|
||||
if let Some(ref bl) = a.blacklist {
|
||||
let mut bhs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in bl { bhs.insert(*n); }
|
||||
pb.blacklist = Some(bhs);
|
||||
}
|
||||
// Check if there is anything in the requires list and add any values
|
||||
if let Some(ref r) = a.requires {
|
||||
let mut rhs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in r { rhs.insert(*n); }
|
||||
pb.requires = Some(rhs);
|
||||
}
|
||||
// Check if there is anything in the possible values and add those as well
|
||||
if let Some(ref p) = a.possible_vals {
|
||||
let mut phs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in p { phs.insert(*n); }
|
||||
pb.possible_vals = Some(phs);
|
||||
}
|
||||
self.positionals_idx.insert(i, pb);
|
||||
} else if a.takes_value {
|
||||
if a.short.is_none() && a.long.is_none() {
|
||||
panic!("Argument \"{}\" has take_value(true), yet neither a short() or long() were supplied", a.name);
|
||||
}
|
||||
// No need to check for .index() as that is handled above
|
||||
|
||||
self.opts.insert(a.name, OptBuilder {
|
||||
let mut ob = OptBuilder {
|
||||
name: a.name,
|
||||
short: a.short,
|
||||
long: a.long,
|
||||
multiple: a.multiple,
|
||||
blacklist: a.blacklist,
|
||||
blacklist: None,
|
||||
help: a.help,
|
||||
requires: a.requires,
|
||||
possible_vals: None,
|
||||
requires: None,
|
||||
required: a.required,
|
||||
});
|
||||
};
|
||||
// Check if there is anything in the blacklist (mutually excludes list) and add any values
|
||||
if let Some(ref bl) = a.blacklist {
|
||||
let mut bhs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in bl { bhs.insert(*n); }
|
||||
ob.blacklist = Some(bhs);
|
||||
}
|
||||
// Check if there is anything in the requires list and add any values
|
||||
if let Some(ref r) = a.requires {
|
||||
let mut rhs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in r { rhs.insert(*n); }
|
||||
ob.requires = Some(rhs);
|
||||
}
|
||||
// Check if there is anything in the possible values and add those as well
|
||||
if let Some(ref p) = a.possible_vals {
|
||||
let mut phs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in p { phs.insert(*n); }
|
||||
ob.possible_vals = Some(phs);
|
||||
}
|
||||
self.opts.insert(a.name, ob);
|
||||
} else {
|
||||
if let Some(ref l) = a.long {
|
||||
if *l == "help" {
|
||||
|
@ -265,15 +311,30 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
// if self.required.contains(a.name) {
|
||||
// self.required.remove(a.name);
|
||||
// }
|
||||
self.flags.insert(a.name, FlagBuilder {
|
||||
let mut fb = FlagBuilder {
|
||||
name: a.name,
|
||||
short: a.short,
|
||||
long: a.long,
|
||||
help: a.help,
|
||||
blacklist: a.blacklist,
|
||||
blacklist: None,
|
||||
multiple: a.multiple,
|
||||
requires: a.requires,
|
||||
});
|
||||
requires: None,
|
||||
};
|
||||
// Check if there is anything in the blacklist (mutually excludes list) and add any values
|
||||
if let Some(ref bl) = a.blacklist {
|
||||
let mut bhs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in bl { bhs.insert(*n); }
|
||||
fb.blacklist = Some(bhs);
|
||||
}
|
||||
// Check if there is anything in the requires list and add any values
|
||||
if let Some(ref r) = a.requires {
|
||||
let mut rhs = HashSet::new();
|
||||
// without derefing n = &&str
|
||||
for n in r { rhs.insert(*n); }
|
||||
fb.requires = Some(rhs);
|
||||
}
|
||||
self.flags.insert(a.name, fb);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -289,7 +350,7 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
/// Arg::new("debug").short("d")])
|
||||
/// # .get_matches();
|
||||
/// ```
|
||||
pub fn args(mut self, args: Vec<Arg<'ar, 'ar, 'ar, 'ar, 'ar>>) -> App<'a, 'v, 'ab, 'u, 'ar> {
|
||||
pub fn args(mut self, args: Vec<Arg<'ar, 'ar, 'ar, 'ar, 'ar, 'ar>>) -> App<'a, 'v, 'ab, 'u, 'ar> {
|
||||
for arg in args.into_iter() {
|
||||
self = self.arg(arg);
|
||||
}
|
||||
|
@ -411,7 +472,7 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
println!("\t{}{}\t{}",
|
||||
if let Some(s) = v.short{format!("-{}",s)}else{" ".to_owned()},
|
||||
if let Some(l) = v.long {format!(",--{}",l)}else {" \t".to_owned()},
|
||||
if let Some(h) = v.help {h} else {" "} );
|
||||
v.help.unwrap_or(" ") );
|
||||
}
|
||||
}
|
||||
if opts {
|
||||
|
@ -423,7 +484,16 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
if let Some(s) = v.short{format!("-{} ",s)}else{" ".to_owned()},
|
||||
if let Some(l) = v.long {format!(",--{}=",l)}else {needs_tab = true; " ".to_owned()},
|
||||
format!("{}", v.name),
|
||||
if let Some(h) = v.help {if needs_tab {format!("\t{}", h)} else { format!("{}", h) } } else {" ".to_owned()} );
|
||||
if let Some(h) = v.help {
|
||||
format!("{}{}{}",
|
||||
if needs_tab { "\t" } else { "" },
|
||||
h,
|
||||
if let Some(ref pv) = v.possible_vals {
|
||||
format!(" [values:{}]", pv.iter().fold(String::new(), |acc, name| acc + &format!("{}",name)[..] ))
|
||||
}else{"".to_owned()})
|
||||
} else {
|
||||
" ".to_owned()
|
||||
} );
|
||||
}
|
||||
}
|
||||
if pos {
|
||||
|
@ -431,7 +501,15 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
println!("POSITIONAL ARGUMENTS:");
|
||||
for v in self.positionals_idx.values() {
|
||||
println!("\t{}\t\t{}", v.name,
|
||||
if let Some(h) = v.help {h} else {" "} );
|
||||
if let Some(h) = v.help {
|
||||
format!("{}{}",
|
||||
h,
|
||||
if let Some(ref pv) = v.possible_vals {
|
||||
format!(" [values:{}]", pv.iter().fold(String::new(), |acc, name| acc + &format!(" {}",name)[..] ))
|
||||
}else{"".to_owned()})
|
||||
} else {
|
||||
" ".to_owned()
|
||||
} );
|
||||
}
|
||||
}
|
||||
if subcmds {
|
||||
|
@ -455,9 +533,9 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
unsafe { libc::exit(0); }
|
||||
}
|
||||
|
||||
fn report_error(&self, msg: String, help: bool, quit: bool) {
|
||||
fn report_error(&self, msg: String, usage: bool, quit: bool) {
|
||||
println!("{}", msg);
|
||||
if help { self.print_usage(true); }
|
||||
if usage { self.print_usage(true); }
|
||||
if quit { env::set_exit_status(1); self.exit(); }
|
||||
}
|
||||
|
||||
|
@ -492,6 +570,20 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
if !pos_only {
|
||||
if let Some(nvo) = needs_val_of {
|
||||
if let Some(ref opt) = self.opts.get(nvo) {
|
||||
if let Some(ref p_vals) = opt.possible_vals {
|
||||
if !p_vals.is_empty() {
|
||||
if !p_vals.contains(arg_slice) {
|
||||
self.report_error(format!("\"{}\" isn't a valid value for {}{}",
|
||||
arg_slice,
|
||||
if opt.long.is_some() {
|
||||
format!("--{}",opt.long.unwrap())
|
||||
}else{
|
||||
format!("-{}", opt.short.unwrap())
|
||||
},
|
||||
format!("\n\t[valid values:{}]", p_vals.iter().fold(String::new(), |acc, name| acc + &format!(" {}",name)[..] )) ), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if let Some(ref mut o) = matches.opts.get_mut(opt.name) {
|
||||
o.values.push(arg.clone());
|
||||
// if it's multiple the occurrences are increased when originall found
|
||||
|
@ -536,6 +628,16 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
true, true);
|
||||
}
|
||||
|
||||
if let Some(ref p_vals) = p.possible_vals {
|
||||
if !p_vals.is_empty() {
|
||||
if !p_vals.contains(arg_slice) {
|
||||
self.report_error(format!("\"{}\" isn't a valid value for {}{}",
|
||||
arg_slice,
|
||||
p.name,
|
||||
format!("\n\t[valid values:{}]", p_vals.iter().fold(String::new(), |acc, name| acc + &format!(" {}",name)[..] )) ), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
matches.positionals.insert(p.name, PosArg{
|
||||
name: p.name.to_owned(),
|
||||
value: arg.clone(),
|
||||
|
@ -661,6 +763,20 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
if !v.multiple {
|
||||
self.report_error(format!("Argument --{} was supplied more than once, but does not support multiple values", arg), true, true);
|
||||
}
|
||||
if let Some(ref p_vals) = v.possible_vals {
|
||||
if let Some(ref av) = arg_val {
|
||||
if !p_vals.contains(&av[..]) {
|
||||
self.report_error(format!("\"{}\" isn't a valid value for {}{}",
|
||||
arg_val.clone().unwrap_or(arg.to_owned()),
|
||||
if v.long.is_some() {
|
||||
format!("--{}", v.long.unwrap())
|
||||
}else{
|
||||
format!("-{}", v.short.unwrap())
|
||||
},
|
||||
format!("\n\t[valid values:{}]", p_vals.iter().fold(String::new(), |acc, name| acc + &format!(" {}",name)[..] )) ), true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
if arg_val.is_some() {
|
||||
if let Some(ref mut o) = matches.opts.get_mut(v.name) {
|
||||
o.occurrences += 1;
|
||||
|
@ -712,7 +828,8 @@ impl<'a, 'v, 'ab, 'u, 'ar> App<'a, 'v, 'ab, 'u, 'ar>{
|
|||
self.report_error(format!("Argument --{} was supplied more than once, but does not support multiple values", arg), true, true);
|
||||
}
|
||||
|
||||
let mut done = false;
|
||||
let mut
|
||||
done = false;
|
||||
if let Some(ref mut f) = matches.flags.get_mut(v.name) {
|
||||
done = true;
|
||||
f.occurrences = if v.multiple { f.occurrences + 1 } else { 1 };
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
/// .takes_value(true)
|
||||
/// .help("Provides a config file to myprog")
|
||||
/// # ).get_matches();
|
||||
pub struct Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub struct Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
/// The unique name of the argument, required
|
||||
pub name: &'n str,
|
||||
/// The short version (i.e. single character) of the argument, no preceding `-`
|
||||
|
@ -47,12 +47,14 @@ pub struct Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
pub multiple: bool,
|
||||
/// A list of names for other arguments that *may not* be used with this flag
|
||||
pub blacklist: Option<Vec<&'b str>>,
|
||||
/// A list of possible values for an option or positional argument
|
||||
pub possible_vals: Option<Vec<&'p str>>,
|
||||
/// A list of names of other arguments that are *required* to be used when
|
||||
/// this flag is used
|
||||
pub requires: Option<Vec<&'r str>>
|
||||
}
|
||||
|
||||
impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
impl<'n, 'l, 'h, 'b, 'p, 'r> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
/// Creates a new instace of `Arg` using a unique string name.
|
||||
/// The name will be used by the library consumer to get information about
|
||||
/// whether or not the argument was used at runtime.
|
||||
|
@ -70,7 +72,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// Arg::new("conifg")
|
||||
/// # .short("c")
|
||||
/// # ).get_matches();
|
||||
pub fn new(n: &'n str) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn new(n: &'n str) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
Arg {
|
||||
name: n,
|
||||
short: None,
|
||||
|
@ -80,8 +82,9 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
takes_value: false,
|
||||
multiple: false,
|
||||
index: None,
|
||||
blacklist: Some(vec![]),
|
||||
requires: Some(vec![]),
|
||||
possible_vals: None,
|
||||
blacklist: None,
|
||||
requires: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -104,7 +107,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("conifg")
|
||||
/// .short("c")
|
||||
/// # ).get_matches();
|
||||
pub fn short(mut self, s: &str) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn short(mut self, s: &str) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.short = s.trim_left_matches(|c| c == '-').chars().nth(0);
|
||||
self
|
||||
}
|
||||
|
@ -128,7 +131,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("conifg")
|
||||
/// .long("config")
|
||||
/// # ).get_matches();
|
||||
pub fn long(mut self, l: &'l str) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn long(mut self, l: &'l str) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.long = Some(l.trim_left_matches(|c| c == '-'));
|
||||
self
|
||||
}
|
||||
|
@ -145,7 +148,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("conifg")
|
||||
/// .help("The config file used by the myprog")
|
||||
/// # ).get_matches();
|
||||
pub fn help(mut self, h: &'h str) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn help(mut self, h: &'h str) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.help = Some(h);
|
||||
self
|
||||
}
|
||||
|
@ -168,7 +171,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("conifg")
|
||||
/// .required(true)
|
||||
/// # ).get_matches();
|
||||
pub fn required(mut self, r: bool) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn required(mut self, r: bool) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.required = r;
|
||||
self
|
||||
}
|
||||
|
@ -187,11 +190,11 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # let myprog = App::new("myprog").arg(Arg::new("conifg")
|
||||
/// .mutually_excludes("debug")
|
||||
/// # ).get_matches();
|
||||
pub fn mutually_excludes(mut self, name: &'b str) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn mutually_excludes(mut self, name: &'b str) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
if let Some(ref mut vec) = self.blacklist {
|
||||
vec.push(name);
|
||||
} else {
|
||||
self.blacklist = Some(vec![]);
|
||||
self.blacklist = Some(vec![name]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -211,13 +214,13 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// .mutually_excludes_all(
|
||||
/// vec!["debug", "input"])
|
||||
/// # ).get_matches();
|
||||
pub fn mutually_excludes_all(mut self, names: Vec<&'b str>) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn mutually_excludes_all(mut self, names: Vec<&'b str>) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
if let Some(ref mut vec) = self.blacklist {
|
||||
for n in names {
|
||||
vec.push(n);
|
||||
}
|
||||
} else {
|
||||
self.blacklist = Some(vec![]);
|
||||
self.blacklist = Some(names);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -234,11 +237,11 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # let myprog = App::new("myprog").arg(Arg::new("conifg")
|
||||
/// .requires("debug")
|
||||
/// # ).get_matches();
|
||||
pub fn requires(mut self, name: &'r str) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn requires(mut self, name: &'r str) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
vec.push(name);
|
||||
} else {
|
||||
self.requires = Some(vec![]);
|
||||
self.requires = Some(vec![name]);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -257,13 +260,13 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// .requires_all(
|
||||
/// vec!["debug", "input"])
|
||||
/// # ).get_matches();
|
||||
pub fn requires_all(mut self, names: Vec<&'r str>) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn requires_all(mut self, names: Vec<&'r str>) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
if let Some(ref mut vec) = self.requires {
|
||||
for n in names {
|
||||
vec.push(n);
|
||||
}
|
||||
} else {
|
||||
self.requires = Some(vec![]);
|
||||
self.requires = Some(names);
|
||||
}
|
||||
self
|
||||
}
|
||||
|
@ -282,7 +285,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("conifg")
|
||||
/// .takes_value(true)
|
||||
/// # ).get_matches();
|
||||
pub fn takes_value(mut self, tv: bool) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn takes_value(mut self, tv: bool) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.takes_value = tv;
|
||||
self
|
||||
}
|
||||
|
@ -303,7 +306,7 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("conifg")
|
||||
/// .index(1)
|
||||
/// # ).get_matches();
|
||||
pub fn index(mut self, idx: u8) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn index(mut self, idx: u8) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.index = Some(idx);
|
||||
self
|
||||
}
|
||||
|
@ -325,8 +328,33 @@ impl<'n, 'l, 'h, 'b, 'r> Arg<'n, 'l, 'h, 'b, 'r> {
|
|||
/// # Arg::new("debug")
|
||||
/// .multiple(true)
|
||||
/// # ).get_matches();
|
||||
pub fn multiple(mut self, multi: bool) -> Arg<'n, 'l, 'h, 'b, 'r> {
|
||||
pub fn multiple(mut self, multi: bool) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
self.multiple = multi;
|
||||
self
|
||||
}
|
||||
|
||||
/// Specifies a list of possible values for this argument. At runtime, clap verifies that only
|
||||
/// one of the specified values was used, or fails with a usage string.
|
||||
///
|
||||
/// **NOTE:** This setting only applies to options and positional arguments
|
||||
///
|
||||
/// Example:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use clap::{App, Arg};
|
||||
/// # let matches = App::new("myprog")
|
||||
/// # .arg(
|
||||
/// # Arg::new("debug").index(1)
|
||||
/// .possible_values(vec!["fast", "slow"])
|
||||
/// # ).get_matches();
|
||||
pub fn possible_values(mut self, names: Vec<&'p str>) -> Arg<'n, 'l, 'h, 'b, 'p, 'r> {
|
||||
if let Some(ref mut vec) = self.possible_vals {
|
||||
for n in names {
|
||||
vec.push(n);
|
||||
}
|
||||
} else {
|
||||
self.possible_vals = Some(names);
|
||||
}
|
||||
self
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
/// `FlagArg` represents a flag argument for command line applications. Flag arguments
|
||||
/// take no additional values, and are always preceded by either a `-` (single character)
|
||||
/// or `--` (single word, no spaces). `FlagArg` isn't directly used by the end application
|
||||
|
@ -31,11 +33,11 @@ pub struct FlagBuilder<'n> {
|
|||
pub multiple: bool,
|
||||
/// A list of names for other arguments that
|
||||
/// *may not* be used with this flag
|
||||
pub blacklist: Option<Vec<&'n str>>,
|
||||
pub blacklist: Option<HashSet<&'n str>>,
|
||||
/// A list of names of other arguments that
|
||||
/// are *required* to be used when this
|
||||
/// flag is used
|
||||
pub requires: Option<Vec<&'n str>>,
|
||||
pub requires: Option<HashSet<&'n str>>,
|
||||
/// The short version (i.e. single character)
|
||||
/// of the argument, no preceding `-`
|
||||
pub short: Option<char>,
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
/// `OptArg` represents a option argument for command line applications, which is one that
|
||||
/// takes an additional value. Option arguments are always preceded by either a `-`
|
||||
/// (single character) or `--` (single word, no spaces) then followed by a space and the
|
||||
|
@ -32,13 +34,15 @@ pub struct OptBuilder<'n> {
|
|||
/// Allow multiple occurrences of an option argument such as "-c some -c other"
|
||||
pub multiple: bool,
|
||||
/// A list of names for other arguments that *may not* be used with this flag
|
||||
pub blacklist: Option<Vec<&'n str>>,
|
||||
pub blacklist: Option<HashSet<&'n str>>,
|
||||
/// If this is a required by default when using the command line program
|
||||
/// i.e. a configuration file that's required for the program to function
|
||||
/// **NOTE:** required by default means, it is required *until* mutually
|
||||
/// exclusive arguments are evaluated.
|
||||
pub required: bool,
|
||||
/// A list of possible values for this argument
|
||||
pub possible_vals: Option<HashSet<&'n str>>,
|
||||
/// A list of names of other arguments that are *required* to be used when
|
||||
/// this flag is used
|
||||
pub requires: Option<Vec<&'n str>>,
|
||||
pub requires: Option<HashSet<&'n str>>,
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::collections::HashSet;
|
||||
|
||||
/// `PosArg` represents a positional argument, i.e. one that isn't preceded
|
||||
/// by a `-` or `--`. `PosArg` isn't directly used by the end application
|
||||
/// writer, only internally to the `clap` library.
|
||||
|
@ -30,9 +32,11 @@ pub struct PosBuilder<'n> {
|
|||
pub required: bool,
|
||||
/// A list of names of other arguments that are *required* to be used when
|
||||
/// this flag is used
|
||||
pub requires: Option<Vec<&'n str>>,
|
||||
pub requires: Option<HashSet<&'n str>>,
|
||||
/// A list of names for other arguments that *may not* be used with this flag
|
||||
pub blacklist: Option<Vec<&'n str>>,
|
||||
pub blacklist: Option<HashSet<&'n str>>,
|
||||
/// A list of possible values for this argument
|
||||
pub possible_vals: Option<HashSet<&'n str>>,
|
||||
/// The index of the argument
|
||||
pub index: u8
|
||||
}
|
Loading…
Reference in a new issue