summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Geary <rtgnj42@gmail.com>2021-07-21 16:30:37 -0400
committerRyan Geary <rtgnj42@gmail.com>2021-07-23 16:27:02 -0400
commit1970d0cc74bf25afdb71f433b0392208098f4607 (patch)
tree6b167f58430a3feacab6eb86ce10402b76350367
parent03e5ca4c1d235e79f497fe91af2b33c0be013781 (diff)
Improve error handling38-unwrap-on-empty-choice
Create choose::Error and choose::Result Improve error propogation Improve error printing Add tests for negative indices Add get_negative_start_end tests Fixup negative choice indexing Remove most uses of unwrap Fixes #38
-rw-r--r--src/choice.rs1175
-rw-r--r--src/choice/mod.rs267
-rw-r--r--src/choice/test/get_negative_start_end.rs183
-rw-r--r--src/choice/test/is_reverse_range.rs31
-rw-r--r--src/choice/test/mod.rs55
-rw-r--r--src/choice/test/print_choice.rs1002
-rw-r--r--src/error.rs63
-rw-r--r--src/errors.rs23
-rw-r--r--src/main.rs27
-rw-r--r--src/parse.rs2
-rw-r--r--src/parse_error.rs2
-rw-r--r--src/result.rs3
-rw-r--r--test/alphabet.txt19
-rw-r--r--test/choose_-1.txt19
-rw-r--r--test/choose_-2.txt19
-rwxr-xr-xtest/e2e_test.sh2
16 files changed, 1683 insertions, 1209 deletions
diff --git a/src/choice.rs b/src/choice.rs
deleted file mode 100644
index b7e3dfd..0000000
--- a/src/choice.rs
+++ /dev/null
@@ -1,1175 +0,0 @@
-use std::convert::TryInto;
-
-use crate::config::Config;
-use crate::writeable::Writeable;
-use crate::writer::WriteReceiver;
-
-#[derive(Debug)]
-pub struct Choice {
- pub start: isize,
- pub end: isize,
- pub kind: ChoiceKind,
- negative_index: bool,
- reversed: bool,
-}
-
-#[derive(Debug, PartialEq)]
-pub enum ChoiceKind {
- Single,
- RustExclusiveRange,
- RustInclusiveRange,
- ColonRange,
-}
-
-impl Choice {
- pub fn new(start: isize, end: isize, kind: ChoiceKind) -> Self {
- let negative_index = start < 0 || end < 0;
- let reversed = end < start && !(start >= 0 && end < 0);
- Choice {
- start,
- end,
- kind,
- negative_index,
- reversed,
- }
- }
-
- pub fn print_choice<W: WriteReceiver>(
- &self,
- line: &str,
- config: &Config,
- handle: &mut W,
- ) -> std::io::Result<()> {
- if config.opt.character_wise {
- self.print_choice_generic(line.chars(), config, handle)
- } else {
- let line_iter = config
- .separator
- .split(line)
- .filter(|s| !s.is_empty() || config.opt.non_greedy);
- self.print_choice_generic(line_iter, config, handle)
- }
- }
-
- pub fn is_reverse_range(&self) -> bool {
- self.reversed
- }
-
- pub fn has_negative_index(&self) -> bool {
- self.negative_index
- }
-
- fn print_choice_generic<W, T, I>(
- &self,
- mut iter: I,
- config: &Config,
- handle: &mut W,
- ) -> std::io::Result<()>
- where
- W: WriteReceiver,
- T: Writeable,
- I: Iterator<Item = T>,
- {
- if self.is_reverse_range() && !self.has_negative_index() {
- self.print_choice_reverse(iter, config, handle)?;
- } else if self.has_negative_index() {
- self.print_choice_negative(iter, config, handle)?;
- } else {
- if self.start > 0 {
- iter.nth((self.start - 1).try_into().unwrap());
- }
- let range = self.end.checked_sub(self.start).unwrap();
- Choice::print_choice_loop_max_items(iter, config, handle, range)?;
- }
-
- Ok(())
- }
-
- fn print_choice_loop_max_items<W, T, I>(
- iter: I,
- config: &Config,
- handle: &mut W,
- max_items: isize,
- ) -> std::io::Result<()>
- where
- W: WriteReceiver,
- T: Writeable,
- I: Iterator<Item = T>,
- {
- let mut peek_iter = iter.peekable();
- for i in 0..=max_items {
- match peek_iter.next() {
- Some(s) => {
- handle.write_choice(s, config, peek_iter.peek().is_some() && i != max_items)?;
- }
- None => break,
- };
- }
-
- Ok(())
- }
-
- fn print_choice_negative<W, T, I>(
- &self,
- iter: I,
- config: &Config,
- handle: &mut W,
- ) -> std::io::Result<()>
- where
- W: WriteReceiver,
- T: Writeable,
- I: Iterator<Item = T>,
- {
- let vec = iter.collect::<Vec<_>>();
- let (start, end) = self.get_negative_start_end(&vec);
-
- if end > start {
- for word in vec[start..std::cmp::min(end, vec.len() - 1)].iter() {
- handle.write_choice(*word, config, true)?;
- }
- handle.write_choice(vec[std::cmp::min(end, vec.len() - 1)], config, false)?;
- } else if self.start < 0 {
- for word in vec[end + 1..=std::cmp::min(start, vec.len() - 1)]
- .iter()
- .rev()
- {
- handle.write_choice(*word, config, true)?;
- }
- handle.write_choice(vec[end], config, false)?;
- }
-
- Ok(())
- }
-
- fn print_choice_reverse<W, T, I>(
- &self,
- mut iter: I,
- config: &Config,
- handle: &mut W,
- ) -> std::io::Result<()>
- where
- W: WriteReceiver,
- T: Writeable,
- I: Iterator<Item = T>,
- {
- if self.end > 0 {
- iter.nth((self.end - 1).try_into().unwrap());
- }
-
- let mut stack = Vec::new();
- for i in 0..=(self.start - self.end) {
- match iter.next() {
- Some(s) => stack.push(s),
- None => break,
- }
-
- if self.start <= self.end + i {
- break;
- }
- }
-
- let mut peek_iter = stack.iter().rev().peekable();
- while let Some(s) = peek_iter.next() {
- handle.write_choice(*s, config, peek_iter.peek().is_some())?;
- }
-
- Ok(())
- }
-
- fn get_negative_start_end<T>(&self, slice: &[T]) -> (usize, usize) {
- let start = if self.start >= 0 {
- self.start.try_into().unwrap()
- } else {
- slice
- .len()
- .checked_sub(self.start.abs().try_into().unwrap())
- .unwrap()
- };
-
- let end = if self.end >= 0 {
- self.end.try_into().unwrap()
- } else {
- slice
- .len()
- .checked_sub(self.end.abs().try_into().unwrap())
- .unwrap()
- };
-
- (start, end)
- }
-}
-
-#[cfg(test)]
-mod tests {
-
- use crate::config::Config;
- use crate::opt::Opt;
- use std::ffi::OsString;
- use std::io::{self, BufWriter, Write};
- use structopt::StructOpt;
-
- impl Config {
- pub fn from_iter<I>(iter: I) -> Self
- where
- I: IntoIterator,
- I::Item: Into<OsString> + Clone,
- {
- Config::new(Opt::from_iter(iter))
- }
- }
-
- struct MockStdout {
- pub buffer: String,
- }
-
- impl MockStdout {
- fn new() -> Self {
- MockStdout {
- buffer: String::new(),
- }
- }
-
- fn str_from_buf_writer(b: BufWriter<MockStdout>) -> String {
- match b.into_inner() {
- Ok(b) => b.buffer,
- Err(_) => panic!("Failed to access BufWriter inner writer"),
- }
- .trim_end()
- .to_string()
- }
- }
-
- impl Write for MockStdout {
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- let mut bytes_written = 0;
- for i in buf {
- self.buffer.push(*i as char);
- bytes_written += 1;
- }
- Ok(bytes_written)
- }
-
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
- }
-
- mod print_choice_tests {
- use super::*;
-
- fn test_fn(vec: Vec<&str>, input: &str, output: &str) {
- let config = Config::from_iter(vec);
- let mut handle = BufWriter::new(MockStdout::new());
-
- config.opt.choices[0]
- .print_choice(&String::from(input), &config, &mut handle)
- .unwrap();
-
- assert_eq!(
- String::from(output),
- MockStdout::str_from_buf_writer(handle)
- );
- }
-
- #[test]
- fn print_0() {
- test_fn(vec!["choose", "0"], "rust is pretty cool", "rust");
- }
-
- #[test]
- fn print_after_end() {
- test_fn(vec!["choose", "10"], "rust is pretty cool", "");
- }
-
- #[test]
- fn print_out_of_order() {
- let config = Config::from_iter(vec!["choose", "3", "1"]);
- let mut handle = BufWriter::new(MockStdout::new());
- let mut handle1 = BufWriter::new(MockStdout::new());
-
- config.opt.choices[0]
- .print_choice(&String::from("rust is pretty cool"), &config, &mut handle)
- .unwrap();
-
- assert_eq!(
- String::from("cool"),
- MockStdout::str_from_buf_writer(handle)
- );
-
- config.opt.choices[1]
- .print_choice(&String::from("rust is pretty cool"), &config, &mut handle1)
- .unwrap();
-
- assert_eq!(String::from("is"), MockStdout::str_from_buf_writer(handle1));
- }
-
- #[test]
- fn print_1_to_3_exclusive() {
- test_fn(
- vec!["choose", "1:3", "-x"],
- "rust is pretty cool",
- "is pretty",
- );
- }
-
- #[test]
- fn print_1_to_3() {
- test_fn(
- vec!["choose", "1:3"],
- "rust is pretty cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_hashtag() {
- test_fn(
- vec!["choose", "1:3", "-f", "#"],
- "rust#is#pretty#cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_varying_multiple_hashtag_exclusive() {
- test_fn(
- vec!["choose", "1:3", "-f", "#", "-x"],
- "rust##is###pretty####cool",
- "is pretty",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_varying_multiple_hashtag() {
- test_fn(
- vec!["choose", "1:3", "-f", "#"],
- "rust##is###pretty####cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_regex_group_vowels_exclusive() {
- test_fn(
- vec!["choose", "1:3", "-f", "[aeiou]", "-x"],
- "the quick brown fox jumped over the lazy dog",
- " q ck br",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_regex_group_vowels() {
- test_fn(
- vec!["choose", "1:3", "-f", "[aeiou]"],
- "the quick brown fox jumped over the lazy dog",
- " q ck br wn f",
- );
- }
-
- #[test]
- fn print_3_to_1() {
- test_fn(
- vec!["choose", "3:1"],
- "rust lang is pretty darn cool",
- "pretty is lang",
- );
- }
-
- #[test]
- fn print_3_to_1_exclusive() {
- test_fn(
- vec!["choose", "3:1", "-x"],
- "rust lang is pretty darn cool",
- "is lang",
- );
- }
-
- #[test]
- fn print_1_to_3_nonexistant_field_separator() {
- test_fn(
- vec!["choose", "1:3", "-f", "#"],
- "rust lang is pretty darn cool",
- "",
- );
- }
-
- #[test]
- fn print_0_nonexistant_field_separator() {
- test_fn(
- vec!["choose", "0", "-f", "#"],
- "rust lang is pretty darn cool",
- "rust lang is pretty darn cool",
- );
- }
-
- #[test]
- fn print_0_to_3_nonexistant_field_separator() {
- test_fn(
- vec!["choose", "0:3", "-f", "#"],
- "rust lang is pretty darn cool",
- "rust lang is pretty darn cool",
- );
- }
-
- #[test]
- fn print_0_with_preceding_separator() {
- test_fn(
- vec!["choose", "0"],
- " rust lang is pretty darn cool",
- "rust",
- );
- }
-
- #[test]
- fn print_neg3_to_neg1() {
- test_fn(
- vec!["choose", "-3:-1"],
- "rust lang is pretty darn cool",
- "pretty darn cool",
- );
- }
-
- #[test]
- fn print_neg1_to_neg3() {
- test_fn(
- vec!["choose", "-1:-3"],
- "rust lang is pretty darn cool",
- "cool darn pretty",
- );
- }
-
- #[test]
- fn print_neg2_to_end() {
- test_fn(
- vec!["choose", "-2:"],
- "rust lang is pretty darn cool",
- "darn cool",
- );
- }
-
- #[test]
- fn print_start_to_neg3() {
- test_fn(
- vec!["choose", ":-3"],
- "rust lang is pretty darn cool",
- "rust lang is pretty",
- );
- }
-
- #[test]
- fn print_1_to_neg3() {
- test_fn(
- vec!["choose", "1:-3"],
- "rust lang is pretty darn cool",
- "lang is pretty",
- );
- }
-
- #[test]
- fn print_5_to_neg3_empty() {
- test_fn(vec!["choose", "5:-3"], "rust lang is pretty darn cool", "");
- }
-
- #[test]
- fn print_0_to_2_greedy() {
- test_fn(vec!["choose", "0:2", "-f", ":"], "a:b::c:::d", "a b c");
- }
-
- #[test]
- fn print_0_to_2_non_greedy() {
- test_fn(vec!["choose", "0:2", "-n", "-f", ":"], "a:b::c:::d", "a b");
- }
-
- #[test]
- fn print_2_to_neg_1_non_greedy_negative() {
- test_fn(vec!["choose", "2:-1", "-n", "-f", ":"], "a:b::c:::d", "c d");
- }
-
- #[test]
- fn print_2_to_0_non_greedy_reversed() {
- test_fn(vec!["choose", "2:0", "-n", "-f", ":"], "a:b::c:::d", "b a");
- }
-
- #[test]
- fn print_neg_1_to_neg_3_non_greedy_negative_reversed() {
- test_fn(vec!["choose", "-1:-3", "-n", "-f", ":"], "a:b::c:::d", "d");
- }
-
- #[test]
- fn print_1_to_3_with_output_field_separator() {
- test_fn(vec!["choose", "1:3", "-o", "#"], "a b c d", "b#c#d");
- }
-
- #[test]
- fn print_1_and_3_with_output_field_separator() {
- test_fn(vec!["choose", "1", "3", "-o", "#"], "a b c d", "b");
- }
-
- #[test]
- fn print_2_to_4_with_output_field_separator() {
- test_fn(
- vec!["choose", "2:4", "-o", "%"],
- "Lorem ipsum dolor sit amet, consectetur",
- "dolor%sit%amet,",
- );
- }
-
- #[test]
- fn print_3_to_1_with_output_field_separator() {
- test_fn(vec!["choose", "3:1", "-o", "#"], "a b c d", "d#c#b");
- }
-
- #[test]
- fn print_0_to_neg_2_with_output_field_separator() {
- test_fn(vec!["choose", "0:-2", "-o", "#"], "a b c d", "a#b#c");
- }
-
- #[test]
- fn print_0_to_2_with_empty_output_field_separator() {
- test_fn(vec!["choose", "0:2", "-o", ""], "a b c d", "abc");
- }
-
- #[test]
- fn print_0_to_2_character_wise() {
- test_fn(vec!["choose", "0:2", "-c"], "abcd", "abc");
- }
-
- #[test]
- fn print_2_to_end_character_wise() {
- test_fn(vec!["choose", "2:", "-c"], "abcd", "cd");
- }
-
- #[test]
- fn print_start_to_2_character_wise() {
- test_fn(vec!["choose", ":2", "-c"], "abcd", "abc");
- }
-
- #[test]
- fn print_0_to_2_character_wise_exclusive() {
- test_fn(vec!["choose", "0:2", "-c", "-x"], "abcd", "ab");
- }
-
- #[test]
- fn print_0_to_2_character_wise_with_output_delimeter() {
- test_fn(vec!["choose", "0:2", "-c", "-o", ":"], "abcd", "a:b:c");
- }
-
- #[test]
- fn print_after_end_character_wise() {
- test_fn(vec!["choose", "0:9", "-c"], "abcd", "abcd");
- }
-
- #[test]
- fn print_2_to_0_character_wise() {
- test_fn(vec!["choose", "2:0", "-c"], "abcd", "cba");
- }
-
- #[test]
- fn print_neg_2_to_end_character_wise() {
- test_fn(vec!["choose", "-2:", "-c"], "abcd", "cd");
- }
-
- #[test]
- fn print_1_to_3_exclusive_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-x"],
- "rust is pretty cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3"],
- "rust is pretty cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_hashtag_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-f", "#"],
- "rust#is#pretty#cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_varying_multiple_hashtag_exclusive_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-f", "#", "-x"],
- "rust##is###pretty####cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_varying_multiple_hashtag_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-f", "#"],
- "rust##is###pretty####cool",
- "is pretty cool",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_regex_group_vowels_exclusive_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-f", "[aeiou]", "-x"],
- "the quick brown fox jumped over the lazy dog",
- " q ck br wn f",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_regex_group_vowels_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-f", "[aeiou]"],
- "the quick brown fox jumped over the lazy dog",
- " q ck br wn f",
- );
- }
-
- #[test]
- fn print_3_to_1_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "3..=1"],
- "rust lang is pretty darn cool",
- "pretty is lang",
- );
- }
-
- #[test]
- fn print_3_to_1_exclusive_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "3..=1", "-x"],
- "rust lang is pretty darn cool",
- "pretty is lang",
- );
- }
-
- #[test]
- fn print_1_to_3_nonexistant_field_separator_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=3", "-f", "#"],
- "rust lang is pretty darn cool",
- "",
- );
- }
-
- #[test]
- fn print_0_to_3_nonexistant_field_separator_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "0..=3", "-f", "#"],
- "rust lang is pretty darn cool",
- "rust lang is pretty darn cool",
- );
- }
-
- #[test]
- fn print_neg1_to_neg1_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "-3..=-1"],
- "rust lang is pretty darn cool",
- "pretty darn cool",
- );
- }
-
- #[test]
- fn print_neg1_to_neg3_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "-1..=-3"],
- "rust lang is pretty darn cool",
- "cool darn pretty",
- );
- }
-
- #[test]
- fn print_neg2_to_end_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "-2..="],
- "rust lang is pretty darn cool",
- "darn cool",
- );
- }
-
- #[test]
- fn print_start_to_neg3_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "..=-3"],
- "rust lang is pretty darn cool",
- "rust lang is pretty",
- );
- }
-
- #[test]
- fn print_1_to_neg3_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "1..=-3"],
- "rust lang is pretty darn cool",
- "lang is pretty",
- );
- }
-
- #[test]
- fn print_5_to_neg3_empty_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "5..=-3"],
- "rust lang is pretty darn cool",
- "",
- );
- }
-
- #[test]
- fn print_0_to_2_greedy_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=2", "-f", ":"], "a:b::c:::d", "a b c");
- }
-
- #[test]
- fn print_0_to_2_non_greedy_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "0..=2", "-n", "-f", ":"],
- "a:b::c:::d",
- "a b",
- );
- }
-
- #[test]
- fn print_2_to_neg_1_non_greedy_negative_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "2..=-1", "-n", "-f", ":"],
- "a:b::c:::d",
- "c d",
- );
- }
-
- #[test]
- fn print_2_to_0_non_greedy_reversed_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "2..=0", "-n", "-f", ":"],
- "a:b::c:::d",
- "b a",
- );
- }
-
- #[test]
- fn print_neg_1_to_neg_3_non_greedy_negative_reversed_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "-1..=-3", "-n", "-f", ":"],
- "a:b::c:::d",
- "d",
- );
- }
-
- #[test]
- fn print_1_to_3_with_output_field_separator_rust_syntax_inclusive() {
- test_fn(vec!["choose", "1..=3", "-o", "#"], "a b c d", "b#c#d");
- }
-
- #[test]
- fn print_1_and_3_with_output_field_separator_rust_syntax_inclusive() {
- let config = Config::from_iter(vec!["choose", "1", "3", "-o", "#"]);
- let mut handle = BufWriter::new(MockStdout::new());
- config.opt.choices[0]
- .print_choice(&String::from("a b c d"), &config, &mut handle)
- .unwrap();
- handle.write(&config.output_separator).unwrap();
- config.opt.choices[1]
- .print_choice(&String::from("a b c d"), &config, &mut handle)
- .unwrap();
- assert_eq!(String::from("b#d"), MockStdout::str_from_buf_writer(handle));
- }
-
- #[test]
- fn print_2_to_4_with_output_field_separator_rust_syntax_inclusive() {
- test_fn(
- vec!["choose", "2..=4", "-o", "%"],
- "Lorem ipsum dolor sit amet, consectetur",
- "dolor%sit%amet,",
- );
- }
-
- #[test]
- fn print_3_to_1_with_output_field_separator_rust_syntax_inclusive() {
- test_fn(vec!["choose", "3..=1", "-o", "#"], "a b c d", "d#c#b");
- }
-
- #[test]
- fn print_0_to_neg_2_with_output_field_separator_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=-2", "-o", "#"], "a b c d", "a#b#c");
- }
-
- #[test]
- fn print_0_to_2_with_empty_output_field_separator_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=2", "-o", ""], "a b c d", "abc");
- }
-
- #[test]
- fn print_0_to_2_character_wise_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=2", "-c"], "abcd", "abc");
- }
-
- #[test]
- fn print_2_to_end_character_wise_rust_syntax_inclusive() {
- test_fn(vec!["choose", "2..=", "-c"], "abcd", "cd");
- }
-
- #[test]
- fn print_start_to_2_character_wise_rust_syntax_inclusive() {
- test_fn(vec!["choose", "..=2", "-c"], "abcd", "abc");
- }
-
- #[test]
- fn print_0_to_2_character_wise_exclusive_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=2", "-c", "-x"], "abcd", "abc");
- }
-
- #[test]
- fn print_0_to_2_character_wise_with_output_delimeter_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=2", "-c", "-o", ":"], "abcd", "a:b:c");
- }
-
- #[test]
- fn print_after_end_character_wise_rust_syntax_inclusive() {
- test_fn(vec!["choose", "0..=9", "-c"], "abcd", "abcd");
- }
-
- #[test]
- fn print_2_to_0_character_wise_rust_syntax_inclusive() {
- test_fn(vec!["choose", "2..=0", "-c"], "abcd", "cba");
- }
-
- #[test]
- fn print_neg_2_to_end_character_wise_rust_syntax_inclusive() {
- test_fn(vec!["choose", "-2..=", "-c"], "abcd", "cd");
- }
-
- #[test]
- fn print_1_to_3_exclusive_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-x"],
- "rust is pretty cool",
- "is pretty",
- );
- }
-
- #[test]
- fn print_1_to_3_rust_syntax_exclusive() {
- test_fn(vec!["choose", "1..3"], "rust is pretty cool", "is pretty");
- }
-
- #[test]
- fn print_1_to_3_separated_by_hashtag_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-f", "#"],
- "rust#is#pretty#cool",
- "is pretty",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_varying_multiple_hashtag_exclusive_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-f", "#", "-x"],
- "rust##is###pretty####cool",
- "is pretty",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_varying_multiple_hashtag_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-f", "#"],
- "rust##is###pretty####cool",
- "is pretty",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_regex_group_vowels_exclusive_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-f", "[aeiou]", "-x"],
- "the quick brown fox jumped over the lazy dog",
- " q ck br",
- );
- }
-
- #[test]
- fn print_1_to_3_separated_by_regex_group_vowels_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-f", "[aeiou]"],
- "the quick brown fox jumped over the lazy dog",
- " q ck br",
- );
- }
-
- #[test]
- fn print_3_to_1_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "3..1"],
- "rust lang is pretty darn cool",
- "is lang",
- );
- }
-
- #[test]
- fn print_3_to_1_exclusive_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "3..1", "-x"],
- "rust lang is pretty darn cool",
- "is lang",
- );
- }
-
- #[test]
- fn print_1_to_3_nonexistant_field_separator_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..3", "-f", "#"],
- "rust lang is pretty darn cool",
- "",
- );
- }
-
- #[test]
- fn print_0_to_3_nonexistant_field_separator_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "0..3", "-f", "#"],
- "rust lang is pretty darn cool",
- "rust lang is pretty darn cool",
- );
- }
-
- #[test]
- fn print_neg3_to_neg1_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "-3..-1"],
- "rust lang is pretty darn cool",
- "pretty darn",
- );
- }
-
- #[test]
- fn print_neg1_to_neg3_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "-1..-3"],
- "rust lang is pretty darn cool",
- "darn pretty",
- );
- }
-
- #[test]
- fn print_neg2_to_end_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "-2.."],
- "rust lang is pretty darn cool",
- "darn cool",
- );
- }
-
- #[test]
- fn print_start_to_neg3_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "..-3"],
- "rust lang is pretty darn cool",
- "rust lang is",
- );
- }
-
- #[test]
- fn print_1_to_neg3_rust_syntax_exclusive() {
- test_fn(
- vec!["choose", "1..-3"],
- "rust lang is pretty darn cool",
- "lang is",
- );
- }
-
- #[test]
- fn print_5_to_neg3_empty_rust_syntax_exclusive() {
- test_fn(vec!["choose", "5..-3"], "rust lang is pretty darn cool", "");
- }
-
- #[test]
- fn print_0_to_2_greedy_rust_syntax_exclusive() {
- test_fn(vec!["choose", "0..2", "-f", ":"], "a:b::c:::d", "a b");
- }
-
- #[test]
- fn print_0_to_2_non_greedy_rust_syntax_exclusive() {
- test_fn(vec!["choose", "0..2", "-n", "-f", ":"], "a:b::c:::d", "a b");
- }
-
- #[test]
- fn print_2_to_neg_1_non_greedy_negative_rust_syntax_exclusive() {
- test_fn(vec!["choose", "2..-1", "-n", "-f", ":"], "a:b::c:::d", "c");
- }
-
- #[test]
- fn print_2_to_0_non_greedy_reversed_rust_syntax_exclusive() {
- test_fn(vec!["choose", "2.