diff options
author | Abin Simon <abinsimon10@gmail.com> | 2021-02-15 10:32:16 +0530 |
---|---|---|
committer | Abin Simon <abinsimon10@gmail.com> | 2021-02-16 09:15:48 +0530 |
commit | 7fad2056826d9cb110cb68b6103f1b55d85cfdef (patch) | |
tree | b2ffd215359b3e05d6a3fda3ffb672fea9e000f7 | |
parent | 24e6335e0a73a24ba7138e5510b3db7ce5d19051 (diff) |
Fix arg value parsing for flags that allow multiple input
-rw-r--r-- | CHANGELOG.md | 1 | ||||
-rw-r--r-- | src/flags/color.rs | 14 | ||||
-rw-r--r-- | src/flags/date.rs | 9 | ||||
-rw-r--r-- | src/flags/icons.rs | 24 | ||||
-rw-r--r-- | src/flags/recursion.rs | 21 | ||||
-rw-r--r-- | src/flags/size.rs | 9 | ||||
-rw-r--r-- | src/flags/sorting.rs | 27 |
7 files changed, 96 insertions, 9 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 88d0830..9564504 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Fix handling blocks passed without -l in cli from [meain](https://github.com/meain) - Fixed sorting of . and .. when used with folder from [meain](https://github.com/meain) +- Fix arg parsing for flags that allow multiple values from [meain](https://github.com/meain) ## [0.19.0] - 2020-12-13 ### Added diff --git a/src/flags/color.rs b/src/flags/color.rs index b3e2fc9..9cede91 100644 --- a/src/flags/color.rs +++ b/src/flags/color.rs @@ -63,7 +63,7 @@ impl Configurable<Self> for ColorOption { if matches.is_present("classic") { Some(Self::Never) } else if matches.occurrences_of("color") > 0 { - if let Some(color) = matches.value_of("color") { + if let Some(color) = matches.values_of("color")?.last() { Self::from_str(&color) } else { panic!("Bad color args. This should not be reachable!"); @@ -124,7 +124,7 @@ mod test_color_option { } #[test] - fn test_from_arg_matches_autp() { + fn test_from_arg_matches_auto() { let argv = vec!["lsd", "--color", "auto"]; let matches = app::build().get_matches_from_safe(argv).unwrap(); assert_eq!( @@ -154,6 +154,16 @@ mod test_color_option { } #[test] + fn test_from_arg_matches_color_multiple() { + let argv = vec!["lsd", "--color", "always", "--color", "never"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert_eq!( + Some(ColorOption::Never), + ColorOption::from_arg_matches(&matches) + ); + } + + #[test] fn test_from_config_none() { assert_eq!(None, ColorOption::from_config(&Config::with_none())); } diff --git a/src/flags/date.rs b/src/flags/date.rs index f7421d5..624b460 100644 --- a/src/flags/date.rs +++ b/src/flags/date.rs @@ -54,7 +54,7 @@ impl Configurable<Self> for DateFlag { if matches.is_present("classic") { Some(Self::Date) } else if matches.occurrences_of("date") > 0 { - match matches.value_of("date") { + match matches.values_of("date")?.last() { Some("date") => Some(Self::Date), Some("relative") => Some(Self::Relative), Some(format) if format.starts_with('+') => { @@ -169,6 +169,13 @@ mod test { } #[test] + fn test_from_arg_matches_date_multi() { + let argv = vec!["lsd", "--date", "relative", "--date", "date"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert_eq!(Some(DateFlag::Date), DateFlag::from_arg_matches(&matches)); + } + + #[test] fn test_from_config_none() { assert_eq!(None, DateFlag::from_config(&Config::with_none())); } diff --git a/src/flags/icons.rs b/src/flags/icons.rs index 03c5d2d..78d0fc6 100644 --- a/src/flags/icons.rs +++ b/src/flags/icons.rs @@ -55,7 +55,7 @@ impl Configurable<Self> for IconOption { if matches.is_present("classic") { Some(Self::Never) } else if matches.occurrences_of("icon") > 0 { - match matches.value_of("icon") { + match matches.values_of("icon")?.last() { Some("always") => Some(Self::Always), Some("auto") => Some(Self::Auto), Some("never") => Some(Self::Never), @@ -107,7 +107,7 @@ impl Configurable<Self> for IconTheme { /// [Some]. Otherwise this returns [None]. fn from_arg_matches(matches: &ArgMatches) -> Option<Self> { if matches.occurrences_of("icon-theme") > 0 { - match matches.value_of("icon-theme") { + match matches.values_of("icon-theme")?.last() { Some("fancy") => Some(Self::Fancy), Some("unicode") => Some(Self::Unicode), _ => panic!("This should not be reachable!"), @@ -229,6 +229,16 @@ mod test_icon_option { } #[test] + fn test_from_arg_matches_icon_when_multi() { + let argv = vec!["lsd", "--icon", "always", "--icon", "never"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert_eq!( + Some(IconOption::Never), + IconOption::from_arg_matches(&matches) + ); + } + + #[test] fn test_from_config_none() { assert_eq!(None, IconOption::from_config(&Config::with_none())); } @@ -315,6 +325,16 @@ mod test_icon_theme { } #[test] + fn test_from_arg_matches_icon_multi() { + let argv = vec!["lsd", "--icon-theme", "fancy", "--icon-theme", "unicode"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert_eq!( + Some(IconTheme::Unicode), + IconTheme::from_arg_matches(&matches) + ); + } + + #[test] fn test_from_config_none() { assert_eq!(None, IconTheme::from_config(&Config::with_none())); } diff --git a/src/flags/recursion.rs b/src/flags/recursion.rs index 54c8b1e..0120be7 100644 --- a/src/flags/recursion.rs +++ b/src/flags/recursion.rs @@ -98,7 +98,11 @@ impl Recursion { /// If the parameter to the "depth" argument can not be parsed, this returns an [Error] in a /// [Some]. fn depth_from_arg_matches(matches: &ArgMatches) -> Option<Result<usize, Error>> { - if let Some(str) = matches.value_of("depth") { + let depth = match matches.values_of("depth") { + Some(d) => d.last(), + None => None, + }; + if let Some(str) = depth { match str.parse::<usize>() { Ok(value) => return Some(Ok(value)), Err(_) => { @@ -215,6 +219,21 @@ mod test { } #[test] + fn test_depth_from_arg_matches_depth_multi() { + let argv = vec!["lsd", "--depth", "4", "--depth", "2"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert!(match Recursion::depth_from_arg_matches(&matches) { + None => false, + Some(result) => { + match result { + Ok(value) => value == 2, + Err(_) => false, + } + } + }); + } + + #[test] fn test_depth_from_arg_matches_neg_int() { let argv = vec!["lsd", "--depth", "\\-42"]; let matches = app::build().get_matches_from_safe(argv).unwrap(); diff --git a/src/flags/size.rs b/src/flags/size.rs index 8ab899f..d609301 100644 --- a/src/flags/size.rs +++ b/src/flags/size.rs @@ -44,7 +44,7 @@ impl Configurable<Self> for SizeFlag { /// [None]. fn from_arg_matches(matches: &ArgMatches) -> Option<Self> { if matches.occurrences_of("size") > 0 { - if let Some(size) = matches.value_of("size") { + if let Some(size) = matches.values_of("size")?.last() { return Self::from_str(size); } } @@ -108,6 +108,13 @@ mod test { } #[test] + fn test_from_arg_matches_size_multi() { + let args = vec!["lsd", "--size", "bytes", "--size", "short"]; + let matches = app::build().get_matches_from_safe(args).unwrap(); + assert_eq!(Some(SizeFlag::Short), SizeFlag::from_arg_matches(&matches)); + } + + #[test] fn test_from_config_none() { assert_eq!(None, SizeFlag::from_config(&Config::with_none())); } diff --git a/src/flags/sorting.rs b/src/flags/sorting.rs index 4f4239e..550486c 100644 --- a/src/flags/sorting.rs +++ b/src/flags/sorting.rs @@ -50,7 +50,10 @@ impl Configurable<Self> for SortColumn { /// If either the "timesort" or "sizesort" arguments are passed, this returns the corresponding /// `SortColumn` variant in a [Some]. Otherwise this returns [None]. fn from_arg_matches(matches: &ArgMatches) -> Option<Self> { - let sort = matches.value_of("sort"); + let sort = match matches.values_of("sort") { + Some(s) => s.last(), + None => None, + }; if matches.is_present("timesort") || sort == Some("time") { Some(Self::Time) } else if matches.is_present("sizesort") || sort == Some("size") { @@ -169,7 +172,7 @@ impl Configurable<Self> for DirGrouping { } if matches.occurrences_of("group-dirs") > 0 { - if let Some(group_dirs) = matches.value_of("group-dirs") { + if let Some(group_dirs) = matches.values_of("group-dirs")?.last() { return Self::from_str(group_dirs); } } @@ -288,6 +291,16 @@ mod test_sort_column { } #[test] + fn test_multi_sort() { + let argv = vec!["lsd", "--sort", "size", "--sort", "time"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert_eq!( + Some(SortColumn::Time), + SortColumn::from_arg_matches(&matches) + ); + } + + #[test] fn test_multi_sort_use_last() { let argv = vec!["lsd", "--sort", "size", "-t", "-S", "-X", "--sort", "time"]; let matches = app::build().get_matches_from_safe(argv).unwrap(); @@ -506,6 +519,16 @@ mod test_dir_grouping { } #[test] + fn test_from_arg_matches_group_dirs_multi() { + let argv = vec!["lsd", "--group-dirs", "first", "--group-dirs", "last"]; + let matches = app::build().get_matches_from_safe(argv).unwrap(); + assert_eq!( + Some(DirGrouping::Last), + DirGrouping::from_arg_matches(&matches) + ); + } + + #[test] fn test_from_config_empty() { assert_eq!(None, DirGrouping::from_config(&Config::with_none())); } |