From 7bcaa341b8685ba411d206c1a89dc3ca77aa71bb Mon Sep 17 00:00:00 2001 From: Max Verevkin Date: Fri, 1 Apr 2022 21:50:19 +0300 Subject: initial commit --- src/lines_buffer.rs | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 src/lines_buffer.rs (limited to 'src/lines_buffer.rs') diff --git a/src/lines_buffer.rs b/src/lines_buffer.rs new file mode 100644 index 0000000..7813ea2 --- /dev/null +++ b/src/lines_buffer.rs @@ -0,0 +1,54 @@ +use std::borrow::Cow; +use std::io::{BufRead, BufReader, Read, Result}; + +pub struct LinesBuffer { + reader: BufReader, + next_line: Vec, +} + +impl LinesBuffer { + pub fn new(inner: R) -> Self { + Self { + reader: BufReader::new(inner), + next_line: Vec::new(), + } + } + + pub fn fill_buf(&mut self) -> Result<()> { + self.reader.fill_buf()?; + Ok(()) + } + + pub fn inner(&self) -> &R { + self.reader.get_ref() + } +} + +impl Iterator for &mut LinesBuffer { + type Item = String; + + fn next(&mut self) -> Option { + let pending = self.reader.buffer(); + let (result, used) = match memchr::memchr(b'\n', pending) { + None => { + self.next_line.extend_from_slice(pending); + (None, pending.len()) + } + Some(i) => { + self.next_line.extend_from_slice(&pending[..i]); + let line = from_utf8(&self.next_line); + self.next_line.clear(); + (Some(line), i + 1) + } + }; + self.reader.consume(used); + result + } +} + +fn from_utf8(bytes: &[u8]) -> String { + match String::from_utf8_lossy(bytes) { + Cow::Borrowed(s) => s.to_owned(), + Cow::Owned(s) => s, + } +} -- cgit v1.3.1