simple_lines 0.0.1

Simple and secure line iterators to be used with all implementations of std::io::Read
Documentation
use {
    linereader::LineReader,
    std::{io::Read, rc::Rc},
};

pub struct RcLineIterator<TRead: Read> {
    line_reader: LineReader<TRead>,
    max_size: usize,
    buffer: Rc<String>,
    pending_incomplete: bool,
}

impl<T: Read> RcLineIterator<T> {
    pub fn new(line_reader: LineReader<T>, max_size: usize) -> Self {
        Self {
            line_reader,
            max_size,
            buffer: Rc::new(String::new()),
            pending_incomplete: false,
        }
    }
}

impl<TRead: Read> Iterator for RcLineIterator<TRead> {
    type Item = Result<Rc<String>, crate::Error<Rc<String>>>;
    fn next(&mut self) -> Option<Result<Rc<String>, crate::Error<Rc<String>>>> {
        let buffer = &mut self.buffer;
        let max_size = self.max_size;
        let pending_incomplete = &mut self.pending_incomplete;

        self.line_reader.next_line().map(move |line| {
            let mut line = line?;
            let contains_delimiter = line.last() == Some(&b'\n');
            if contains_delimiter {
                line = &line[0..line.len() - 1];
                if line.last() == Some(&b'\r') {
                    line = &line[0..line.len() - 1];
                }
            }
            let owned = if let Some(r) = Rc::get_mut(buffer) {
                r.clear();
                r
            } else {
                *buffer = Rc::new(String::with_capacity(line.len()));
                Rc::get_mut(buffer).unwrap()
            };
            let line_str = std::str::from_utf8(line)?;
            owned.push_str(line_str);

            if max_size == buffer.len() {
                *pending_incomplete = true;
                Err(crate::Error::Incomplete(buffer.clone()))
            } else if *pending_incomplete {
                *pending_incomplete = false;
                Err(crate::Error::Incomplete(buffer.clone()))
            } else {
                Ok(buffer.clone())
            }
        })
    }
}