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}