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