From ab119b342aafe4807f64de4b748348650e91420f Mon Sep 17 00:00:00 2001 From: liudingming Date: Sat, 31 Jul 2021 16:55:54 +0800 Subject: [PATCH] Fix value_of returns None when the first value group is empty --- src/parse/matches/arg_matches.rs | 6 +++--- src/parse/matches/matched_arg.rs | 14 ++++++++++++-- tests/default_missing_vals.rs | 33 +++++++++++++++++++++++++++++++- 3 files changed, 47 insertions(+), 6 deletions(-) diff --git a/src/parse/matches/arg_matches.rs b/src/parse/matches/arg_matches.rs index f0b5a1d9..1d0ef635 100644 --- a/src/parse/matches/arg_matches.rs +++ b/src/parse/matches/arg_matches.rs @@ -121,7 +121,7 @@ impl ArgMatches { /// [`occurrences_of`]: crate::ArgMatches::occurrences_of() pub fn value_of(&self, id: T) -> Option<&str> { if let Some(arg) = self.args.get(&Id::from(id)) { - if let Some(v) = arg.get_val(0) { + if let Some(v) = arg.first() { return Some(v.to_str().expect(INVALID_UTF8)); } } @@ -158,7 +158,7 @@ impl ArgMatches { /// [`Arg::values_of_lossy`]: ArgMatches::values_of_lossy() pub fn value_of_lossy(&self, id: T) -> Option> { if let Some(arg) = self.args.get(&Id::from(id)) { - if let Some(v) = arg.get_val(0) { + if let Some(v) = arg.first() { return Some(v.to_string_lossy()); } } @@ -199,7 +199,7 @@ impl ArgMatches { pub fn value_of_os(&self, id: T) -> Option<&OsStr> { self.args .get(&Id::from(id)) - .and_then(|arg| arg.get_val(0).map(OsString::as_os_str)) + .and_then(|arg| arg.first().map(OsString::as_os_str)) } /// Gets a [`Values`] struct which implements [`Iterator`] for values of a specific argument diff --git a/src/parse/matches/matched_arg.rs b/src/parse/matches/matched_arg.rs index c3d35f92..89a6a8a4 100644 --- a/src/parse/matches/matched_arg.rs +++ b/src/parse/matches/matched_arg.rs @@ -62,8 +62,8 @@ impl MatchedArg { self.vals.iter().flatten() } - pub(crate) fn get_val(&self, index: usize) -> Option<&OsString> { - self.vals.get(0)?.get(index) + pub(crate) fn first(&self) -> Option<&OsString> { + self.vals_flatten().next() } pub(crate) fn push_val(&mut self, val: OsString) { @@ -190,6 +190,16 @@ mod tests { ); } + #[test] + fn test_grouped_vals_first() { + let mut m = MatchedArg::new(); + m.new_val_group(); + m.new_val_group(); + m.append_val("bbb".into()); + m.append_val("ccc".into()); + assert_eq!(m.first(), Some(&OsString::from("bbb"))); + } + #[test] fn test_grouped_vals_push_and_append() { let mut m = MatchedArg::new(); diff --git a/tests/default_missing_vals.rs b/tests/default_missing_vals.rs index a352aa2f..ec2f62bc 100644 --- a/tests/default_missing_vals.rs +++ b/tests/default_missing_vals.rs @@ -1,4 +1,4 @@ -use clap::{App, Arg}; +use clap::{App, Arg, ArgMatches}; #[test] fn opt_missing() { @@ -108,3 +108,34 @@ fn opt_default_user_override() { assert!(m.is_present("o")); assert_eq!(m.value_of("o").unwrap(), "value"); } + +#[test] +fn default_missing_value_flag_value() { + let app = App::new("test").arg( + Arg::new("flag") + .long("flag") + .takes_value(true) + .default_missing_value("true"), + ); + + fn flag_value(m: ArgMatches) -> bool { + match m.value_of("flag") { + None => false, + Some(x) => x.parse().expect("non boolean value"), + } + } + + assert_eq!(flag_value(app.clone().get_matches_from(&["test"])), false); + assert_eq!( + flag_value(app.clone().get_matches_from(&["test", "--flag"])), + true + ); + assert_eq!( + flag_value(app.clone().get_matches_from(&["test", "--flag=true"])), + true + ); + assert_eq!( + flag_value(app.clone().get_matches_from(&["test", "--flag=false"])), + false + ); +}