1
use std::io::BufRead;
2
use std::io::BufReader;
3
use std::io::Read;
4
use streaming_iterator::StreamingIterator;
5

            
6
/// A lending iterator over the lines of a type implementing Read.
7
pub struct LineIterator<T: Read> {
8
    reader: BufReader<T>,
9
    buffer: String,
10
    end: bool,
11
}
12

            
13
impl<T: Read> LineIterator<T> {
14
114
    pub fn new(reader: T) -> LineIterator<T> {
15
114
        LineIterator {
16
114
            reader: BufReader::new(reader),
17
114
            buffer: String::new(),
18
114
            end: false,
19
114
        }
20
114
    }
21
}
22

            
23
impl<T: Read> StreamingIterator for LineIterator<T> {
24
    type Item = String;
25

            
26
216815
    fn advance(&mut self) {
27
216815
        self.buffer.clear();
28
216815
        match self.reader.read_line(&mut self.buffer) {
29
216815
            Ok(n) if n > 0 => {
30
216703
                if self.buffer.ends_with('\n') {
31
216697
                    self.buffer.pop();
32
216697
                    if self.buffer.ends_with('\r') {
33
281
                        self.buffer.pop();
34
216416
                    }
35
6
                }
36
            }
37
112
            Ok(_) => self.end = true,
38
            Err(_) => self.end = true,
39
        }
40
216815
    }
41

            
42
216815
    fn get(&self) -> Option<&Self::Item> {
43
216815
        if self.end { None } else { Some(&self.buffer) }
44
216815
    }
45
}
46

            
47
#[cfg(test)]
48
mod tests {
49
    use super::*;
50

            
51
    use std::io::Cursor;
52

            
53
    #[test]
54
1
    fn test_line_iterator_basic() {
55
1
        let data = "line1\nline2\nline3";
56
1
        let cursor = Cursor::new(data);
57
1
        let mut line_iterator = LineIterator::new(cursor);
58

            
59
1
        let mut lines = Vec::new();
60
4
        while let Some(line) = line_iterator.next() {
61
3
            lines.push(line.clone());
62
3
        }
63

            
64
1
        assert_eq!(lines, vec!["line1", "line2", "line3"]);
65
1
    }
66

            
67
    #[test]
68
1
    fn test_line_iterator_empty() {
69
1
        let data = "";
70
1
        let cursor = Cursor::new(data);
71
1
        let mut line_iterator = LineIterator::new(cursor);
72

            
73
1
        let mut lines = Vec::new();
74
1
        while let Some(line) = line_iterator.next() {
75
            lines.push(line.clone());
76
        }
77

            
78
1
        assert!(lines.is_empty());
79
1
    }
80

            
81
    #[test]
82
1
    fn test_line_iterator_single_line() {
83
1
        let data = "single line";
84
1
        let cursor = Cursor::new(data);
85
1
        let mut line_iterator = LineIterator::new(cursor);
86

            
87
1
        let mut lines = Vec::new();
88
2
        while let Some(line) = line_iterator.next() {
89
1
            lines.push(line.clone());
90
1
        }
91

            
92
1
        assert_eq!(lines, vec!["single line"]);
93
1
    }
94

            
95
    #[test]
96
1
    fn test_line_iterator_with_carriage_return() {
97
1
        let data = "line1\r\nline2\r\nline3";
98
1
        let cursor = Cursor::new(data);
99
1
        let mut line_iterator = LineIterator::new(cursor);
100

            
101
1
        let mut lines = Vec::new();
102
4
        while let Some(line) = line_iterator.next() {
103
3
            lines.push(line.clone());
104
3
        }
105

            
106
1
        assert_eq!(lines, vec!["line1", "line2", "line3"]);
107
1
    }
108
}