summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAbin Simon <abinsimon10@gmail.com>2021-02-15 10:32:16 +0530
committerAbin Simon <abinsimon10@gmail.com>2021-02-16 09:15:48 +0530
commit7fad2056826d9cb110cb68b6103f1b55d85cfdef (patch)
treeb2ffd215359b3e05d6a3fda3ffb672fea9e000f7
parent24e6335e0a73a24ba7138e5510b3db7ce5d19051 (diff)
Fix arg value parsing for flags that allow multiple input
-rw-r--r--CHANGELOG.md1
-rw-r--r--src/flags/color.rs14
-rw-r--r--src/flags/date.rs9
-rw-r--r--src/flags/icons.rs24
-rw-r--r--src/flags/recursion.rs21
-rw-r--r--src/flags/size.rs9
-rw-r--r--src/flags/sorting.rs27
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()));
}