Add reverse ranges

This commit is contained in:
Ryan Geary 2019-10-13 21:40:59 -04:00
parent e7169ea2e8
commit 0be16bf1d9
2 changed files with 86 additions and 17 deletions

View file

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

View file

@ -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