summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRyan Geary <rtgnj42@gmail.com>2020-04-04 18:05:32 -0400
committerRyan Geary <rtgnj42@gmail.com>2020-04-04 18:09:37 -0400
commitd40c9d5234e4388b6321f9bea2f4b43e748b59fd (patch)
tree6c69e03c165dff7e89b4ed825b96535af33e8ec4
parent024edfc8f405fa2c08350d0caa492e68ad5b7005 (diff)
Non-greedy String Splitting (#7)
* Add non_greedy flag * Add non-greedy tests * Prevent printing spaces for empty fields * Prevent filtering non-empty fields when non-greedy
-rw-r--r--src/choice.rs67
-rw-r--r--src/opt.rs4
2 files changed, 63 insertions, 8 deletions
diff --git a/src/choice.rs b/src/choice.rs
index 63ddb2e..941f512 100644
--- a/src/choice.rs
+++ b/src/choice.rs
@@ -29,7 +29,10 @@ impl Choice {
config: &Config,
handle: &mut BufWriter<WriterType>,
) {
- let mut line_iter = config.separator.split(line).filter(|s| !s.is_empty());
+ let mut line_iter = config
+ .separator
+ .split(line)
+ .filter(|s| !s.is_empty() || config.opt.non_greedy);
if self.is_reverse_range() && !self.has_negative_index() {
if self.end > 0 {
@@ -101,13 +104,18 @@ impl Choice {
}
fn write_bytes<WriterType: Write>(handle: &mut BufWriter<WriterType>, b: &[u8]) {
- match handle.write(b) {
- Ok(_) => (),
- Err(e) => eprintln!("Failed to write to output: {}", e),
- }
- match handle.write(b" ") {
- Ok(_) => (),
- Err(e) => eprintln!("Failed to write to output: {}", e),
+ let num_bytes_written = match handle.write(b) {
+ Ok(x) => x,
+ Err(e) => {
+ eprintln!("Failed to write to output: {}", e);
+ 0
+ }
+ };
+ if num_bytes_written > 0 {
+ match handle.write(b" ") {
+ Ok(_) => (),
+ Err(e) => eprintln!("Failed to write to output: {}", e),
+ }
}
}
@@ -513,6 +521,49 @@ mod tests {
);
assert_eq!(String::from(""), MockStdout::str_from_buf_writer(handle));
}
+
+ #[test]
+ fn print_0_to_2_greedy() {
+ let config = Config::from_iter(vec!["choose", "0:2", "-f", ":"]);
+ let mut handle = BufWriter::new(MockStdout::new());
+ config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
+ assert_eq!(
+ String::from("a b c"),
+ MockStdout::str_from_buf_writer(handle)
+ );
+ }
+
+ #[test]
+ fn print_0_to_2_non_greedy() {
+ let config = Config::from_iter(vec!["choose", "0:2", "-n", "-f", ":"]);
+ let mut handle = BufWriter::new(MockStdout::new());
+ config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
+ assert_eq!(String::from("a b"), MockStdout::str_from_buf_writer(handle));
+ }
+
+ #[test]
+ fn print_2_to_neg_1_non_greedy_negative() {
+ let config = Config::from_iter(vec!["choose", "2:-1", "-n", "-f", ":"]);
+ let mut handle = BufWriter::new(MockStdout::new());
+ config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
+ assert_eq!(String::from("c d"), MockStdout::str_from_buf_writer(handle));
+ }
+
+ #[test]
+ fn print_2_to_0_non_greedy_reversed() {
+ let config = Config::from_iter(vec!["choose", "2:0", "-n", "-f", ":"]);
+ let mut handle = BufWriter::new(MockStdout::new());
+ config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
+ assert_eq!(String::from("b a"), MockStdout::str_from_buf_writer(handle));
+ }
+
+ #[test]
+ fn print_neg_1_to_neg_3_non_greedy_negative_reversed() {
+ let config = Config::from_iter(vec!["choose", "-1:-3", "-n", "-f", ":"]);
+ let mut handle = BufWriter::new(MockStdout::new());
+ config.opt.choice[0].print_choice(&String::from("a:b::c:::d"), &config, &mut handle);
+ assert_eq!(String::from("d"), MockStdout::str_from_buf_writer(handle));
+ }
}
mod is_reverse_range_tests {
diff --git a/src/opt.rs b/src/opt.rs
index 77fc710..4170fb7 100644
--- a/src/opt.rs
+++ b/src/opt.rs
@@ -12,6 +12,10 @@ pub struct Opt {
#[structopt(short, long)]
pub field_separator: Option<String>,
+ /// Use non-greedy field separators
+ #[structopt(short, long)]
+ pub non_greedy: bool,
+
/// Use exclusive ranges, similar to array indexing in many programming languages
#[structopt(short = "x", long)]
pub exclusive: bool,