From c4e04c53842a62eb8b02a3e3b8da853062a44a9e Mon Sep 17 00:00:00 2001 From: Hanif Bin Ariffin Date: Sun, 18 Jul 2021 13:34:30 +0800 Subject: [PATCH] Implemented squeeze operation Signed-off-by: Hanif Bin Ariffin --- src/uu/tr/src/operation.rs | 77 +++++++++++++++++++++++++++++++++++++- src/uu/tr/src/tr.rs | 15 +++++--- 2 files changed, 85 insertions(+), 7 deletions(-) diff --git a/src/uu/tr/src/operation.rs b/src/uu/tr/src/operation.rs index 96884c3cd..72c0158f3 100644 --- a/src/uu/tr/src/operation.rs +++ b/src/uu/tr/src/operation.rs @@ -304,7 +304,18 @@ impl SymbolTranslatorNew for DeleteOperationNew { #[derive(Debug, Clone)] pub enum TranslateOperationNew { Standard(HashMap), - Complement(u32, Vec, Vec, char, HashMap), + Complement( + // iter + u32, + // set 1 + Vec, + // set 2 + Vec, + // fallback + char, + // translation map + HashMap, + ), } impl TranslateOperationNew { @@ -388,6 +399,70 @@ impl SymbolTranslatorNew for TranslateOperationNew { } } +#[derive(Debug, Clone)] +pub struct SqueezeOperationNew { + squeeze_set: Vec, + complement: bool, + previous: Option, +} + +impl SqueezeOperationNew { + pub fn new(squeeze_set: Vec, complement: bool) -> SqueezeOperationNew { + SqueezeOperationNew { + squeeze_set: squeeze_set + .into_iter() + .flat_map(Sequence::dissolve) + .collect(), + complement, + previous: None, + } + } +} + +impl SymbolTranslatorNew for SqueezeOperationNew { + fn translate(&mut self, current: char) -> Option { + if self.complement { + if self.squeeze_set.iter().any(|c| c.eq(¤t)) { + Some(current) + } else { + match self.previous { + Some(v) => { + if v.eq(¤t) { + None + } else { + self.previous = Some(current); + Some(current) + } + } + None => { + self.previous = Some(current); + Some(current) + } + } + } + } else { + if self.squeeze_set.iter().any(|c| c.eq(¤t)) { + match self.previous { + Some(v) => { + if v.eq(¤t) { + None + } else { + self.previous = Some(current); + Some(current) + } + } + None => { + self.previous = Some(current); + Some(current) + } + } + } else { + Some(current) + } + } + } +} + pub fn translate_input_new(input: &mut dyn BufRead, output: &mut dyn Write, mut translator: T) where T: SymbolTranslatorNew, diff --git a/src/uu/tr/src/tr.rs b/src/uu/tr/src/tr.rs index a5b6d04b7..286e7b023 100644 --- a/src/uu/tr/src/tr.rs +++ b/src/uu/tr/src/tr.rs @@ -20,7 +20,7 @@ mod operation; use bit_set::BitSet; use clap::{crate_version, App, Arg}; use fnv::FnvHashMap; -use operation::{translate_input_new, Sequence, TranslateOperationNew}; +use operation::{translate_input_new, Sequence, SqueezeOperationNew, TranslateOperationNew}; use std::io::{stdin, stdout, BufRead, BufWriter, Write}; use crate::{expand::ExpandSet, operation::DeleteOperationNew}; @@ -278,11 +278,13 @@ pub fn uumain(args: impl uucore::Args) -> i32 { let locked_stdout = stdout.lock(); let mut buffered_stdout = BufWriter::new(locked_stdout); - let set1 = ExpandSet::new(sets[0].as_ref()); if delete_flag { if squeeze_flag { - let set2 = ExpandSet::new(sets[1].as_ref()); - let op = DeleteAndSqueezeOperation::new(set1, set2, complement_flag); + let op = DeleteAndSqueezeOperation::new( + ExpandSet::new(sets[0].as_ref()), + ExpandSet::new(sets[1].as_ref()), + complement_flag, + ); translate_input(&mut locked_stdin, &mut buffered_stdout, op); } else { let op = DeleteOperationNew::new(Sequence::parse_set_string(&sets[0]), complement_flag); @@ -290,8 +292,9 @@ pub fn uumain(args: impl uucore::Args) -> i32 { } } else if squeeze_flag { if sets.len() < 2 { - let op = SqueezeOperation::new(set1, complement_flag); - translate_input(&mut locked_stdin, &mut buffered_stdout, op); + let op = + SqueezeOperationNew::new(Sequence::parse_set_string(&sets[0]), complement_flag); + translate_input_new(&mut locked_stdin, &mut buffered_stdout, op); } else { let op = TranslateAndSqueezeOperation::new(sets, truncate_set1_flag, complement_flag); translate_input(&mut locked_stdin, &mut buffered_stdout, op);