mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-28 11:37:44 +00:00
Merge pull request #2151 from jfinkels/2141-translate-and-squeeze
tr: implement translate and squeeze (-s) mode
This commit is contained in:
commit
7e07438b38
2 changed files with 66 additions and 3 deletions
|
@ -149,6 +149,35 @@ impl SymbolTranslator for TranslateOperation {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct TranslateAndSqueezeOperation {
|
||||||
|
translate: TranslateOperation,
|
||||||
|
squeeze: SqueezeOperation,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TranslateAndSqueezeOperation {
|
||||||
|
fn new(
|
||||||
|
set1: ExpandSet,
|
||||||
|
set2: &mut ExpandSet,
|
||||||
|
set2_: ExpandSet,
|
||||||
|
truncate: bool,
|
||||||
|
complement: bool,
|
||||||
|
) -> TranslateAndSqueezeOperation {
|
||||||
|
TranslateAndSqueezeOperation {
|
||||||
|
translate: TranslateOperation::new(set1, set2, truncate),
|
||||||
|
squeeze: SqueezeOperation::new(set2_, complement),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl SymbolTranslator for TranslateAndSqueezeOperation {
|
||||||
|
fn translate(&self, c: char, prev_c: char) -> Option<char> {
|
||||||
|
// `unwrap()` will never panic because `Translate.translate()`
|
||||||
|
// always returns `Some`.
|
||||||
|
self.squeeze
|
||||||
|
.translate(self.translate.translate(c, 0 as char).unwrap(), prev_c)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn translate_input<T: SymbolTranslator>(
|
fn translate_input<T: SymbolTranslator>(
|
||||||
input: &mut dyn BufRead,
|
input: &mut dyn BufRead,
|
||||||
output: &mut dyn Write,
|
output: &mut dyn Write,
|
||||||
|
@ -166,8 +195,11 @@ fn translate_input<T: SymbolTranslator>(
|
||||||
// isolation to make borrow checker happy
|
// isolation to make borrow checker happy
|
||||||
let filtered = buf.chars().filter_map(|c| {
|
let filtered = buf.chars().filter_map(|c| {
|
||||||
let res = translator.translate(c, prev_c);
|
let res = translator.translate(c, prev_c);
|
||||||
|
// Set `prev_c` to the post-translate character. This
|
||||||
|
// allows the squeeze operation to correctly function
|
||||||
|
// after the translate operation.
|
||||||
if res.is_some() {
|
if res.is_some() {
|
||||||
prev_c = c;
|
prev_c = res.unwrap();
|
||||||
}
|
}
|
||||||
res
|
res
|
||||||
});
|
});
|
||||||
|
@ -290,8 +322,21 @@ pub fn uumain(args: impl uucore::Args) -> i32 {
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
}
|
}
|
||||||
} else if squeeze_flag {
|
} else if squeeze_flag {
|
||||||
|
if sets.len() < 2 {
|
||||||
let op = SqueezeOperation::new(set1, complement_flag);
|
let op = SqueezeOperation::new(set1, complement_flag);
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
|
} else {
|
||||||
|
let mut set2 = ExpandSet::new(sets[1].as_ref());
|
||||||
|
let set2_ = ExpandSet::new(sets[1].as_ref());
|
||||||
|
let op = TranslateAndSqueezeOperation::new(
|
||||||
|
set1,
|
||||||
|
&mut set2,
|
||||||
|
set2_,
|
||||||
|
complement_flag,
|
||||||
|
truncate_flag,
|
||||||
|
);
|
||||||
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
let mut set2 = ExpandSet::new(sets[1].as_ref());
|
let mut set2 = ExpandSet::new(sets[1].as_ref());
|
||||||
let op = TranslateOperation::new(set1, &mut set2, truncate_flag);
|
let op = TranslateOperation::new(set1, &mut set2, truncate_flag);
|
||||||
|
|
|
@ -77,6 +77,24 @@ fn test_squeeze_complement() {
|
||||||
.stdout_is("aaBcDcc");
|
.stdout_is("aaBcDcc");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_translate_and_squeeze() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "x", "y"])
|
||||||
|
.pipe_in("xx")
|
||||||
|
.run()
|
||||||
|
.stdout_is("y");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_translate_and_squeeze_multiple_lines() {
|
||||||
|
new_ucmd!()
|
||||||
|
.args(&["-s", "x", "y"])
|
||||||
|
.pipe_in("xxaax\nxaaxx")
|
||||||
|
.run()
|
||||||
|
.stdout_is("yaay\nyaay");
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_delete_and_squeeze() {
|
fn test_delete_and_squeeze() {
|
||||||
new_ucmd!()
|
new_ucmd!()
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue