diff --git a/src/lib.rs b/src/lib.rs index 743bc11f..6a9be8f5 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -118,6 +118,7 @@ use std::ffi::OsStr; use std::fmt; use std::iter::{repeat, IntoIterator}; use std::result; +use std::str::FromStr; use unicode_width::UnicodeWidthStr; @@ -819,6 +820,33 @@ impl Matches { } } + /// Returns some matching value or `None`. + /// + /// Similar to opt_str, also converts matching argument using FromStr. + pub fn opt_get(&self, nm: &str) -> result::Result, T::Err> + where T: FromStr + { + match self.opt_val(nm) { + Some(Val(s)) => Ok(Some(s.parse()?)), + Some(Given) => Ok(None), + None => Ok(None), + } + } + + /// Returns a matching value or default. + /// + /// Similar to opt_default, except the two differences. + /// Instead of returning None when argument was not present, return `def`. + /// Instead of returning &str return type T, parsed using str::parse(). + pub fn opt_get_default(&self, nm: &str, def: T) + -> result::Result where T: FromStr + { + match self.opt_val(nm) { + Some(Val(s)) => s.parse(), + Some(Given) => Ok(def), + None => Ok(def), + } + } } fn is_arg(arg: &str) -> bool { @@ -2002,4 +2030,70 @@ Options: Err(e) => panic!("{}", e) } } + + #[test] + fn test_opt_default() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + opts.optflag("i", "ignore", "Description"); + opts.optflag("r", "run", "Description"); + opts.long_only(false); + + let args: Vec = ["-i", "-r", "10"] + .iter().map(|x| x.to_string()).collect(); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e) + }; + assert_eq!(matches.opt_default("help", ""), None); + assert_eq!(matches.opt_default("i", "def"), Some("def".to_string())); + } + + #[test] + fn test_opt_get() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + opts.optflagopt("i", "ignore", "Description", "true | false"); + opts.optflagopt("r", "run", "Description", "0 .. 10"); + opts.optflagopt("p", "percent", "Description", "0.0 .. 10.0"); + opts.long_only(false); + + let args: Vec = [ + "-i", "true", "-p", "1.1" + ].iter().map(|x| x.to_string()).collect(); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e) + }; + let h_arg = matches.opt_get::("help"); + assert_eq!(h_arg, Ok(None)); + let i_arg = matches.opt_get("i"); + assert_eq!(i_arg, Ok(Some(true))); + let p_arg = matches.opt_get("p"); + assert_eq!(p_arg, Ok(Some(1.1))); + } + + #[test] + fn test_opt_get_default() { + let mut opts = Options::new(); + opts.optflag("h", "help", "Description"); + opts.optflagopt("i", "ignore", "Description", "true | false"); + opts.optflagopt("r", "run", "Description", "0 .. 10"); + opts.optflagopt("p", "percent", "Description", "0.0 .. 10.0"); + opts.long_only(false); + + let args: Vec = [ + "-i", "true", "-p", "1.1" + ].iter().map(|x| x.to_string()).collect(); + let matches = &match opts.parse(&args) { + Ok(m) => m, + Err(e) => panic!("{}", e) + }; + let h_arg =matches.opt_get_default("help", 10); + assert_eq!(h_arg, Ok(10)); + let i_arg = matches.opt_get_default("i", false); + assert_eq!(i_arg, Ok(true)); + let p_arg = matches.opt_get_default("p", 10.2); + assert_eq!(p_arg, Ok(1.1)); + } }