1
Fork 0
mirror of https://github.com/RGBCube/uutils-coreutils synced 2025-07-28 11:37:44 +00:00

csplit: return UResult instead of io::Result from iterator to handle error message more uniformly.

This commit is contained in:
Fuad Ismail 2024-12-12 11:45:58 +07:00 committed by Daniel Hofstetter
parent 19f990f29a
commit 51dce9c5f8
2 changed files with 25 additions and 10 deletions

View file

@ -87,7 +87,11 @@ pub fn csplit<T>(options: &CsplitOptions, patterns: &[String], input: T) -> Resu
where where
T: BufRead, T: BufRead,
{ {
let mut input_iter = InputSplitter::new(input.lines().enumerate()); let enumerated_input_lines = input
.lines()
.map(|line| line.map_err_context(|| "read error".to_string()))
.enumerate();
let mut input_iter = InputSplitter::new(enumerated_input_lines);
let mut split_writer = SplitWriter::new(options); let mut split_writer = SplitWriter::new(options);
let patterns: Vec<patterns::Pattern> = patterns::get_patterns(patterns)?; let patterns: Vec<patterns::Pattern> = patterns::get_patterns(patterns)?;
let ret = do_csplit(&mut split_writer, patterns, &mut input_iter); let ret = do_csplit(&mut split_writer, patterns, &mut input_iter);
@ -117,7 +121,7 @@ fn do_csplit<I>(
input_iter: &mut InputSplitter<I>, input_iter: &mut InputSplitter<I>,
) -> Result<(), CsplitError> ) -> Result<(), CsplitError>
where where
I: Iterator<Item = (usize, io::Result<String>)>, I: Iterator<Item = (usize, UResult<String>)>,
{ {
// split the file based on patterns // split the file based on patterns
for pattern in patterns { for pattern in patterns {
@ -305,7 +309,7 @@ impl SplitWriter<'_> {
input_iter: &mut InputSplitter<I>, input_iter: &mut InputSplitter<I>,
) -> Result<(), CsplitError> ) -> Result<(), CsplitError>
where where
I: Iterator<Item = (usize, io::Result<String>)>, I: Iterator<Item = (usize, UResult<String>)>,
{ {
input_iter.rewind_buffer(); input_iter.rewind_buffer();
input_iter.set_size_of_buffer(1); input_iter.set_size_of_buffer(1);
@ -358,7 +362,7 @@ impl SplitWriter<'_> {
input_iter: &mut InputSplitter<I>, input_iter: &mut InputSplitter<I>,
) -> Result<(), CsplitError> ) -> Result<(), CsplitError>
where where
I: Iterator<Item = (usize, io::Result<String>)>, I: Iterator<Item = (usize, UResult<String>)>,
{ {
if offset >= 0 { if offset >= 0 {
// The offset is zero or positive, no need for a buffer on the lines read. // The offset is zero or positive, no need for a buffer on the lines read.
@ -470,7 +474,7 @@ impl SplitWriter<'_> {
/// This is used to pass matching lines to the next split and to support patterns with a negative offset. /// This is used to pass matching lines to the next split and to support patterns with a negative offset.
struct InputSplitter<I> struct InputSplitter<I>
where where
I: Iterator<Item = (usize, io::Result<String>)>, I: Iterator<Item = (usize, UResult<String>)>,
{ {
iter: I, iter: I,
buffer: Vec<<I as Iterator>::Item>, buffer: Vec<<I as Iterator>::Item>,
@ -483,7 +487,7 @@ where
impl<I> InputSplitter<I> impl<I> InputSplitter<I>
where where
I: Iterator<Item = (usize, io::Result<String>)>, I: Iterator<Item = (usize, UResult<String>)>,
{ {
fn new(iter: I) -> Self { fn new(iter: I) -> Self {
Self { Self {
@ -547,7 +551,7 @@ where
impl<I> Iterator for InputSplitter<I> impl<I> Iterator for InputSplitter<I>
where where
I: Iterator<Item = (usize, io::Result<String>)>, I: Iterator<Item = (usize, UResult<String>)>,
{ {
type Item = <I as Iterator>::Item; type Item = <I as Iterator>::Item;

View file

@ -35,6 +35,8 @@ pub enum CsplitError {
SuffixFormatTooManyPercents, SuffixFormatTooManyPercents,
#[error("{} is not a regular file", ._0.quote())] #[error("{} is not a regular file", ._0.quote())]
NotRegularFile(String), NotRegularFile(String),
#[error("{}", _0)]
UError(Box<dyn UError>),
} }
impl From<io::Error> for CsplitError { impl From<io::Error> for CsplitError {
@ -43,8 +45,17 @@ impl From<io::Error> for CsplitError {
} }
} }
impl UError for CsplitError { impl From<Box<dyn UError>> for CsplitError {
fn code(&self) -> i32 { fn from(error: Box<dyn UError>) -> Self {
1 Self::UError(error)
}
}
impl UError for CsplitError {
fn code(&self) -> i32 {
match self {
Self::UError(e) => e.code(),
_ => 1,
}
} }
} }