summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Geary <rtgnj42@gmail.com>2019-10-13 21:40:59 -0400
committerRyan Geary <rtgnj42@gmail.com>2019-10-13 21:40:59 -0400
commit0be16bf1d99af669497f7125d9e3eb6b8fb09fad (patch)
treea99a2f62b28501e2f2a91892b24f3565d70e4263
parente7169ea2e817874f9a1f71d55906e04a71aec558 (diff)
Add reverse ranges
-rw-r--r--src/choice.rs101
-rwxr-xr-xtest/e2e_test.sh2
2 files changed, 86 insertions, 17 deletions
diff --git a/src/choice.rs b/src/choice.rs
index 0b48a68..5ee25d1 100644
--- a/src/choice.rs
+++ b/src/choice.rs
@@ -21,6 +21,16 @@ impl Choice {
write!(handle, "{}", self.get_choice_slice(line, config).join(" "));
}
+ pub fn is_reverse_range(&self) -> bool {
+ match self {
+ Choice::Field(_) => false,
+ Choice::FieldRange(r) => match r {
+ (Some(start), Some(end)) => end < start,
+ _ => false,
+ },
+ }
+ }
+
fn get_choice_slice<'a>(&self, line: &'a String, config: &Config) -> Vec<&'a str> {
let words = config
.separator
@@ -29,7 +39,7 @@ impl Choice {
.filter(|s| !s.is_empty())
.enumerate();
- match self {
+ let mut slices = match self {
Choice::Field(i) => words
.filter(|x| x.0 == *i as usize)
.map(|x| x.1)
@@ -58,32 +68,45 @@ impl Choice {
(*end).try_into().unwrap()
};
words
- .filter(|x| x.0 < e && x.0 >= (*start).try_into().unwrap())
+ .filter(|x| {
+ (x.0 < e && x.0 >= (*start).try_into().unwrap())
+ || self.is_reverse_range()
+ && (x.0 > e && x.0 <= (*start).try_into().unwrap())
+ })
.map(|x| x.1)
.collect::<Vec<&str>>()
}
},
- }
+ };
+
+ if self.is_reverse_range() {
+ slices.reverse();
}
+
+ return slices;
+
+}
}
#[cfg(test)]
mod tests {
- mod get_choice_slice_tests {
- use crate::config::{Config, Opt};
- use std::ffi::OsString;
- use structopt::StructOpt;
+ use crate::config::{Config, Opt};
+ use std::ffi::OsString;
+ use structopt::StructOpt;
- impl Config {
- pub fn from_iter<I>(iter: I) -> Self
- where
- I: IntoIterator,
- I::Item: Into<OsString> + Clone,
- {
- return Config::new(Opt::from_iter(iter));
- }
+ impl Config {
+ pub fn from_iter<I>(iter: I) -> Self
+ where
+ I: IntoIterator,
+ I::Item: Into<OsString> + Clone,
+ {
+ return Config::new(Opt::from_iter(iter));
}
+ }
+
+ mod get_choice_slice_tests {
+ use super::*;
#[test]
fn print_0() {
@@ -194,7 +217,53 @@ mod tests {
);
}
+ #[test]
+ fn print_3_to_1() {
+ let config = Config::from_iter(vec!["choose", "3:1"]);
+ assert_eq!(
+ vec!["pretty", "is"],
+ config.opt.choice[0].get_choice_slice(
+ &String::from("rust lang is pretty darn cool"),
+ &config
+ )
+ );
+ }
+
}
-}
+ mod is_reverse_range_tests {
+ use super::*;
+
+ #[test]
+ fn is_field_reversed() {
+ let config = Config::from_iter(vec!["choose", "0"]);
+ assert_eq!(false, config.opt.choice[0].is_reverse_range());
+ }
+
+ #[test]
+ fn is_field_range_no_start_reversed() {
+ let config = Config::from_iter(vec!["choose", ":2"]);
+ assert_eq!(false, config.opt.choice[0].is_reverse_range());
+ }
+
+ #[test]
+ fn is_field_range_no_end_reversed() {
+ let config = Config::from_iter(vec!["choose", "2:"]);
+ assert_eq!(false, config.opt.choice[0].is_reverse_range());
+ }
+
+ #[test]
+ fn is_field_range_no_start_or_end_reversed() {
+ let config = Config::from_iter(vec!["choose", ":"]);
+ assert_eq!(false, config.opt.choice[0].is_reverse_range());
+ }
+ #[test]
+ fn is_reversed_field_range_reversed() {
+ let config = Config::from_iter(vec!["choose", "4:2"]);
+ assert_eq!(true, config.opt.choice[0].is_reverse_range());
+ }
+
+ }
+
+}
diff --git a/test/e2e_test.sh b/test/e2e_test.sh
index 01f54ec..a76b8a2 100755
--- a/test/e2e_test.sh
+++ b/test/e2e_test.sh
@@ -13,7 +13,7 @@ diff -w <(cargo run -- :2 -i ${test_dir}/lorem.txt) <(cat "${test_dir}/choose_:2
diff -w <(cargo run -- 9 3 -i ${test_dir}/lorem.txt) <(cat "${test_dir}/choose_9_3.txt")
diff -w <(cargo run -- 9 -i ${test_dir}/lorem.txt) <(cat "${test_dir}/choose_9.txt")
diff -w <(cargo run -- 12 -i ${test_dir}/lorem.txt) <(cat "${test_dir}/choose_12.txt")
-# add test for reverse range
+diff -w <(cargo run -- 4:1 -i ${test_dir}/lorem.txt) <(cat "${test_dir}/choose_4:1.txt")
# add tests for different delimiters
# add tests using piping