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:
parent
19f990f29a
commit
51dce9c5f8
2 changed files with 25 additions and 10 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue