mailbox/stream/
lines.rs

1//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
2//                    Version 2, December 2004
3//
4// Copyleft (ↄ) meh. <meh@schizofreni.co> | http://meh.schizofreni.co
5//
6// Everyone is permitted to copy and distribute verbatim or modified
7// copies of this license document, and changing it is allowed as long
8// as the name is changed.
9//
10//            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
11//   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
12//
13//  0. You just DO WHAT THE FUCK YOU WANT TO.
14
15use std::io::{self, BufRead};
16
17/// Iterator over ASCII lines.
18///
19/// The content of a line is not assumed to be in any specific encoding.
20pub struct Lines<R: BufRead>(R, u64);
21
22impl<R: BufRead> Lines<R> {
23	/// Create a new `Iterator` from the given input.
24	#[inline]
25	pub fn new(input: R) -> Self {
26		Lines(input, 0)
27	}
28}
29
30impl<R: BufRead> Iterator for Lines<R> {
31	type Item = io::Result<(u64, Vec<u8>)>;
32
33	#[inline]
34	fn next(&mut self) -> Option<Self::Item> {
35		let mut buffer = Vec::new();
36		let     offset = self.1;
37
38		match self.0.read_until(b'\n', &mut buffer) {
39			Ok(0) => {
40				None
41			}
42
43			Ok(_) => {
44				self.1 += buffer.len() as u64;
45
46				if buffer.last() == Some(&b'\n') {
47					buffer.pop();
48
49					if buffer.last() == Some(&b'\r') {
50						buffer.pop();
51					}
52				}
53
54				Some(Ok((offset, buffer)))
55			}
56
57			Err(e) => {
58				Some(Err(e))
59			}
60		}
61	}
62}