From 96d28df88085b3bdfaa07f05fcc79368233a2d53 Mon Sep 17 00:00:00 2001 From: Kevin K Date: Wed, 18 Mar 2015 18:09:42 -0400 Subject: [PATCH] Initial commit for multiple option arguments --- src/app.rs | 23 ++++++++++++++--------- src/args/argmatches.rs | 38 +++++++++++++++++++++++++++++++++++--- src/args/optarg.rs | 4 +++- 3 files changed, 52 insertions(+), 13 deletions(-) diff --git a/src/app.rs b/src/app.rs index e190261f..47f6007e 100644 --- a/src/app.rs +++ b/src/app.rs @@ -218,11 +218,12 @@ impl App { name: a.name, short: a.short, long: a.long, + multiple: a.multiple, blacklist: a.blacklist, help: a.help, requires: a.requires, required: a.required, - value: None + values: None }); } else { if let Some(ref l) = a.long { @@ -450,12 +451,12 @@ impl App { self.print_version(true); } - let mut arg_val: Option = None; + let mut arg_val: Option> = None; if arg.contains("=") { let arg_vec: Vec<&str> = arg.split("=").collect(); arg = arg_vec[0]; - arg_val = Some(arg_vec[1].to_string()); + arg_val = Some(vec![arg_vec[1].to_string()]); } for (k, v) in self.opts.iter() { @@ -465,6 +466,11 @@ impl App { self.report_error(format!("The argument --{} is mutually exclusive with one or more other arguments", arg), true, true); } + let mut name_to_return = Option< + match arg_val { + None => { return Some(v.name); }, + _ => { return None; } + } matches.opts.insert(k, OptArg{ name: v.name, short: v.short, @@ -472,13 +478,11 @@ impl App { help: v.help, required: v.required, blacklist: None, + multiple: v.multiple, requires: None, - value: arg_val.clone() + values: arg_val }); - match arg_val { - None => { return Some(v.name); }, - _ => { return None; } - } + } } } @@ -726,8 +730,9 @@ impl App { help: opt.help, requires: None, blacklist: None, + multiple: opt.multiple, required: opt.required, - value: Some(arg.clone()) + values: Some(vec![arg.clone()]) }); if let Some(ref bl) = opt.blacklist { if ! bl.is_empty() { diff --git a/src/args/argmatches.rs b/src/args/argmatches.rs index 1e37a37a..03eed3d2 100644 --- a/src/args/argmatches.rs +++ b/src/args/argmatches.rs @@ -86,7 +86,10 @@ impl ArgMatches { /// 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 - /// it returns `None` + /// it returns `None`. + /// + /// *NOTE:* If getting a value for an option argument that allows multiples, prefer `values_of()` + /// as `value_of()` will only return the _*first*_ value. /// /// # Example /// @@ -99,8 +102,10 @@ impl ArgMatches { /// ``` pub fn value_of(&self, name: &'static str) -> Option<&String> { if let Some(ref opt) = self.opts.get(name) { - if let Some(ref v) = opt.value { - return Some(v); + if let Some(ref v) = opt.values { + if let Some(ref s) = v.iter().nth(0) { + return Some(s); + } } } if let Some(ref pos) = self.positionals.get(name) { @@ -111,6 +116,33 @@ impl ArgMatches { None } + /// Gets the values of a specific option in a vector (i.e. an argument that takes + /// an additional value at runtime). If the option wasn't present at runtime + /// it returns `None` + /// + /// # Example + /// + /// ```no_run + /// # use clap::{App, Arg}; + /// # let matches = App::new("myapp").arg(Arg::new("output").takes_value(true)).get_matches(); + /// // If the program had option "-c" that took a value and was run + /// // via "myapp -o some -o other -o file" + /// // values_of() would return a [&str; 3] ("some", "other", "file") + /// if let Some(os) = matches.values_of("output") { + /// for o in os { + /// println!("A value for output: {}", o); + /// } + /// } + /// ``` + pub fn values_of(&self, name: &'static str) -> Option> { + if let Some(ref opt) = self.opts.get(name) { + if let Some(ref v) = opt.values { + return Some(v.iter().map(|s| &s[..]).collect::>()); + } + } + None + } + /// Checks if a flag was argument was supplied at runtime. **DOES NOT** work for /// option or positional arguments (use `.value_of()` instead) /// diff --git a/src/args/optarg.rs b/src/args/optarg.rs index 6d3770ed..911dfb5d 100644 --- a/src/args/optarg.rs +++ b/src/args/optarg.rs @@ -31,6 +31,8 @@ pub struct OptArg { pub requires: Option>, /// A list of names for other arguments that *may not* be used with this flag pub blacklist: Option>, + /// Allow multiple values of an option argument + pub multiple: bool, /// The value provided to the argument by the user - pub value: Option + pub values: Option> }