Skip to content

Instantly share code, notes, and snippets.

@jakobrs
Last active December 2, 2022 15:19
Show Gist options
  • Save jakobrs/5fa3f78dc57415790048bdb83af12296 to your computer and use it in GitHub Desktop.
Save jakobrs/5fa3f78dc57415790048bdb83af12296 to your computer and use it in GitHub Desktop.
use std::io::BufRead;
trait LendingIterator {
type Item<'a>
where
Self: 'a;
fn next(&mut self) -> Option<Self::Item<'_>>;
}
struct LinesBuf<Reader: BufRead> {
buf: String,
reader: Reader,
}
impl<Reader: BufRead> LendingIterator for LinesBuf<Reader> {
type Item<'a> = std::io::Result<&'a str> where Reader: 'a;
fn next(&mut self) -> Option<Self::Item<'_>> {
// Adapted from stdlib implementation of Lines
self.buf.clear();
match self.reader.read_line(&mut self.buf) {
Ok(0) => None,
Ok(_n) => {
if self.buf.ends_with('\n') {
self.buf.pop();
if self.buf.ends_with('\r') {
self.buf.pop();
}
}
Some(Ok(&self.buf))
}
Err(e) => Some(Err(e)),
}
}
}
trait BufReadExt: BufRead {
fn lines_buf(self) -> LinesBuf<Self>
where
Self: Sized;
}
impl<T: BufRead> BufReadExt for T {
fn lines_buf(self) -> LinesBuf<Self>
where
Self: Sized,
{
LinesBuf {
buf: String::new(),
reader: self,
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment