diff --git a/src/app.rs b/src/app.rs index dffc8d3b..6f9ba886 100644 --- a/src/app.rs +++ b/src/app.rs @@ -26,7 +26,7 @@ pub struct App { needs_short_version: bool, required: HashSet<&'static str>, arg_list: HashSet<&'static str>, - // blacklist: HashMap<&'static str, Vec<&'static str>> + blacklist: HashSet<&'static str> } impl App { @@ -45,7 +45,8 @@ impl App { needs_short_help: true, needs_short_version: true, required: HashSet::new(), - arg_list: HashSet::new() + arg_list: HashSet::new(), + blacklist: HashSet::new() } } @@ -204,6 +205,10 @@ impl App { if s != arg { continue; } if !matches.flags.contains_key(k) { + if self.blacklist.contains(k) { + self.report_error(&format!("The argument -{} is mutually exclusive with one or more other arguments", arg), + false, true); + } matches.flags.insert(k, v.clone()); if self.required.contains(k) { self.required.remove(k); @@ -218,6 +223,13 @@ impl App { } } } + if let Some(ref bl) = v.blacklist { + if ! bl.is_empty() { + for name in bl.iter() { + self.blacklist.insert(k); + } + } + } } else if matches.flags.get(k).unwrap().multiple { matches.flags.get_mut(k).unwrap().occurrences += 1 } @@ -249,6 +261,10 @@ impl App { for (k, v) in self.opts.iter() { if let Some(ref l) = v.long { if *l == arg { + if self.blacklist.contains(k) { + self.report_error(&format!("The argument --{} is mutually exclusive with one or more other arguments", arg), + false, true); + } matches.opts.insert(k, OptArg{ name: v.name, short: v.short, @@ -279,10 +295,21 @@ impl App { // so the 'if let' must finish it's scope first // before calling .insert() if ! multi { + if self.blacklist.contains(k) { + self.report_error(&format!("The argument --{} is mutually exclusive with one or more other arguments", arg), + false, true); + } matches.flags.insert(k, v.clone()); if self.required.contains(k) { self.required.remove(k); } + if let Some(ref bl) = v.blacklist { + if ! bl.is_empty() { + for name in bl.iter() { + self.blacklist.insert(k); + } + } + } } if let Some(ref reqs) = v.requires { if ! reqs.is_empty() { @@ -360,6 +387,15 @@ impl App { let mut skip = false; if let Some(ref nvo) = needs_val_of { if let Some(ref opt) = self.opts.get(nvo) { + if self.blacklist.contains(opt.name) { + self.report_error( + &format!("The argument {} is mutually exclusive with one or more other arguments", + if let Some(long) = opt.long { + format!("--{}",long) + }else{ + format!("-{}",opt.short.unwrap()) + }),false, true); + } matches.opts.insert(nvo, OptArg{ name: opt.name, short: opt.short, @@ -369,6 +405,13 @@ impl App { required: opt.required, value: Some(arg.clone()) }); + if let Some(ref bl) = opt.blacklist { + if ! bl.is_empty() { + for name in bl.iter() { + self.blacklist.insert(opt.name); + } + } + } if self.required.contains(opt.name) { self.required.remove(opt.name); } @@ -404,6 +447,10 @@ impl App { false, true); } if let Some(ref p) = self.positionals_idx.get(&pos_counter) { + if self.blacklist.contains(p.name) { + self.report_error(&format!("The argument \"{}\" is mutually exclusive with one or more other arguments", arg), + false, true); + } matches.positionals.insert(p.name, PosArg{ name: p.name, help: p.help, @@ -412,6 +459,13 @@ impl App { value: Some(arg.clone()), index: pos_counter }); + if let Some(ref bl) = p.blacklist { + if ! bl.is_empty() { + for name in bl.iter() { + self.blacklist.insert(p.name); + } + } + } if self.required.contains(p.name) { self.required.remove(p.name); } diff --git a/src/argmatches.rs b/src/argmatches.rs index a4db80af..259e0262 100644 --- a/src/argmatches.rs +++ b/src/argmatches.rs @@ -1,11 +1,12 @@ use std::collections::HashMap; +use std::collections::HashSet; use app::App; use args::{ FlagArg, OptArg, PosArg }; pub struct ArgMatches { pub required: Vec<&'static str>, - pub blacklist: Vec<&'static str>, + pub blacklist: HashSet<&'static str>, pub about: Option<&'static str>, pub name: &'static str, pub author: Option<&'static str>, @@ -22,7 +23,7 @@ impl ArgMatches { opts: HashMap::new(), positionals: HashMap::new(), required: vec![], - blacklist: vec![], + blacklist: HashSet::new(), about: app.about, name: app.name, author: app.author, diff --git a/src/args/flagarg.rs b/src/args/flagarg.rs index fe4849b0..8c235f27 100644 --- a/src/args/flagarg.rs +++ b/src/args/flagarg.rs @@ -6,5 +6,6 @@ pub struct FlagArg { pub help: Option<&'static str>, pub multiple: bool, pub occurrences: u8, + pub blacklist: Option>, pub requires: Option> } \ No newline at end of file diff --git a/src/args/optarg.rs b/src/args/optarg.rs index 92a14f48..41039225 100644 --- a/src/args/optarg.rs +++ b/src/args/optarg.rs @@ -5,5 +5,6 @@ pub struct OptArg { pub help: Option<&'static str>, pub required: bool, pub requires: Option>, + pub blacklist: Option>, pub value: Option } diff --git a/src/args/posarg.rs b/src/args/posarg.rs index 85fe19b6..847c5da3 100644 --- a/src/args/posarg.rs +++ b/src/args/posarg.rs @@ -3,6 +3,7 @@ pub struct PosArg { pub help: Option<&'static str>, pub required: bool, pub requires: Option>, + pub blacklist: Option>, pub value: Option, pub index: u8 } \ No newline at end of file