1use std::io::{Read, Result as IoResult,};
2use std::iter::Iterator;
3
4use byte_string::ByteString;
5
6const NEW_LINE: u8 = b'\n';
7const CARRIAGE_RETURN: u8 = b'\r';
8
9pub type ByteLine = ByteString;
10pub type ByteLineResult = IoResult<ByteLine>;
11
12#[derive(Debug, Copy, Clone)]
13pub struct ByteLines<B> {
14 buf: B,
15}
16
17impl<B: Read> Iterator for ByteLines<B> {
18 type Item = ByteLineResult;
19
20 fn next(&mut self) -> Option<ByteLineResult> {
21 let mut buf = vec![];
22 let bytes = self.buf.by_ref().bytes();
23
24 for byte in bytes {
25 if let Ok(byte) = byte {
26 buf.push(byte);
27
28 if is_newline(byte) {
29 break;
30 }
31 }
32 }
33
34 if buf.is_empty() {
35 return None;
36 }
37
38 let byte_str = ByteString::new(buf);
39 Some(Ok(byte_str))
40 }
41}
42
43pub trait ReadByteLines<T> {
44 fn byte_lines(self: Self) -> ByteLines<T>;
45}
46
47impl<T> ReadByteLines<T> for T {
48 fn byte_lines(self: T) -> ByteLines<T> {
49 ByteLines { buf: self }
50 }
51}
52
53fn is_newline(chr: u8) -> bool {
54 chr == NEW_LINE || chr == CARRIAGE_RETURN
55}