Fix value_of returns None when the first value group is empty

This commit is contained in:
liudingming 2021-07-31 16:55:54 +08:00
parent 88dec14775
commit ab119b342a
3 changed files with 47 additions and 6 deletions

View file

@ -121,7 +121,7 @@ impl ArgMatches {
/// [`occurrences_of`]: crate::ArgMatches::occurrences_of()
pub fn value_of<T: Key>(&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<T: Key>(&self, id: T) -> Option<Cow<'_, 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_string_lossy());
}
}
@ -199,7 +199,7 @@ impl ArgMatches {
pub fn value_of_os<T: Key>(&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

View file

@ -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();

View file

@ -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
);
}