mirror of
https://github.com/RGBCube/uutils-coreutils
synced 2025-07-29 03:57:44 +00:00
Merge pull request #6012 from BenWiederhake/dev-tr-stream
tr: Stream output instead of buffering
This commit is contained in:
commit
fe0c814bd5
2 changed files with 39 additions and 25 deletions
|
@ -339,6 +339,32 @@ impl Sequence {
|
||||||
|
|
||||||
pub trait SymbolTranslator {
|
pub trait SymbolTranslator {
|
||||||
fn translate(&mut self, current: u8) -> Option<u8>;
|
fn translate(&mut self, current: u8) -> Option<u8>;
|
||||||
|
|
||||||
|
/// Takes two SymbolTranslators and creates a new SymbolTranslator over both in sequence.
|
||||||
|
///
|
||||||
|
/// This behaves pretty much identical to [`Iterator::chain`].
|
||||||
|
fn chain<T>(self, other: T) -> ChainedSymbolTranslator<Self, T>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
ChainedSymbolTranslator::<Self, T> {
|
||||||
|
stage_a: self,
|
||||||
|
stage_b: other,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct ChainedSymbolTranslator<A, B> {
|
||||||
|
stage_a: A,
|
||||||
|
stage_b: B,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<A: SymbolTranslator, B: SymbolTranslator> SymbolTranslator for ChainedSymbolTranslator<A, B> {
|
||||||
|
fn translate(&mut self, current: u8) -> Option<u8> {
|
||||||
|
self.stage_a
|
||||||
|
.translate(current)
|
||||||
|
.and_then(|c| self.stage_b.translate(c))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
|
|
@ -9,9 +9,10 @@ mod operation;
|
||||||
mod unicode_table;
|
mod unicode_table;
|
||||||
|
|
||||||
use clap::{crate_version, Arg, ArgAction, Command};
|
use clap::{crate_version, Arg, ArgAction, Command};
|
||||||
use nom::AsBytes;
|
use operation::{
|
||||||
use operation::{translate_input, Sequence, SqueezeOperation, TranslateOperation};
|
translate_input, Sequence, SqueezeOperation, SymbolTranslator, TranslateOperation,
|
||||||
use std::io::{stdin, stdout, BufReader, BufWriter};
|
};
|
||||||
|
use std::io::{stdin, stdout, BufWriter};
|
||||||
use uucore::{format_usage, help_about, help_section, help_usage, show};
|
use uucore::{format_usage, help_about, help_section, help_usage, show};
|
||||||
|
|
||||||
use crate::operation::DeleteOperation;
|
use crate::operation::DeleteOperation;
|
||||||
|
@ -117,19 +118,13 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
truncate_set1_flag,
|
truncate_set1_flag,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
|
// '*_op' are the operations that need to be applied, in order.
|
||||||
if delete_flag {
|
if delete_flag {
|
||||||
if squeeze_flag {
|
if squeeze_flag {
|
||||||
let mut delete_buffer = vec![];
|
let delete_op = DeleteOperation::new(set1, complement_flag);
|
||||||
{
|
let squeeze_op = SqueezeOperation::new(set2, false);
|
||||||
let mut delete_writer = BufWriter::new(&mut delete_buffer);
|
let op = delete_op.chain(squeeze_op);
|
||||||
let delete_op = DeleteOperation::new(set1, complement_flag);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
translate_input(&mut locked_stdin, &mut delete_writer, delete_op);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let mut squeeze_reader = BufReader::new(delete_buffer.as_bytes());
|
|
||||||
let op = SqueezeOperation::new(set2, false);
|
|
||||||
translate_input(&mut squeeze_reader, &mut buffered_stdout, op);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let op = DeleteOperation::new(set1, complement_flag);
|
let op = DeleteOperation::new(set1, complement_flag);
|
||||||
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
|
@ -139,17 +134,10 @@ pub fn uumain(args: impl uucore::Args) -> UResult<()> {
|
||||||
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 {
|
} else {
|
||||||
let mut translate_buffer = vec![];
|
let translate_op = TranslateOperation::new(set1, set2.clone(), complement_flag)?;
|
||||||
{
|
let squeeze_op = SqueezeOperation::new(set2, false);
|
||||||
let mut writer = BufWriter::new(&mut translate_buffer);
|
let op = translate_op.chain(squeeze_op);
|
||||||
let op = TranslateOperation::new(set1, set2.clone(), complement_flag)?;
|
translate_input(&mut locked_stdin, &mut buffered_stdout, op);
|
||||||
translate_input(&mut locked_stdin, &mut writer, op);
|
|
||||||
}
|
|
||||||
{
|
|
||||||
let mut reader = BufReader::new(translate_buffer.as_bytes());
|
|
||||||
let squeeze_op = SqueezeOperation::new(set2, false);
|
|
||||||
translate_input(&mut reader, &mut buffered_stdout, squeeze_op);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let op = TranslateOperation::new(set1, set2, complement_flag)?;
|
let op = TranslateOperation::new(set1, set2, complement_flag)?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue