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
30
    pub fn new(reader: T) -> LineIterator<T> {
15
30
        LineIterator {
16
30
            reader: BufReader::new(reader),
17
30
            buffer: String::new(),
18
30
            end: false,
19
30
        }
20
30
    }
21
}
22

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

            
26
164667
    fn advance(&mut self) {
27
164667
        self.buffer.clear();
28
164667
        match self.reader.read_line(&mut self.buffer) {
29
164667
            Ok(n) if n > 0 => {
30
164639
                if self.buffer.ends_with('\n') {
31
164634
                    self.buffer.pop();
32
164634
                    if self.buffer.ends_with('\r') {
33
653
                        self.buffer.pop();
34
164351
                    }
35
5
                }
36
            }
37
28
            Ok(_) => self.end = true,
38
            Err(_) => self.end = true,
39
        }
40
164667
    }
41

            
42
164667
    fn get(&self) -> Option<&Self::Item> {
43
164667
        if self.end {
44
28
            None
45
        } else {
46
164639
            Some(&self.buffer)
47
        }
48
164667
    }
49
}
50

            
51
#[cfg(test)]
52
mod tests {
53
    use super::*;
54

            
55
    use std::io::Cursor;
56

            
57
    #[test]
58
1
    fn test_line_iterator_basic() {
59
1
        let data = "line1\nline2\nline3";
60
1
        let cursor = Cursor::new(data);
61
1
        let mut line_iterator = LineIterator::new(cursor);
62
1

            
63
1
        let mut lines = Vec::new();
64
4
        while let Some(line) = line_iterator.next() {
65
3
            lines.push(line.clone());
66
3
        }
67

            
68
1
        assert_eq!(lines, vec!["line1", "line2", "line3"]);
69
1
    }
70

            
71
    #[test]
72
1
    fn test_line_iterator_empty() {
73
1
        let data = "";
74
1
        let cursor = Cursor::new(data);
75
1
        let mut line_iterator = LineIterator::new(cursor);
76
1

            
77
1
        let mut lines = Vec::new();
78
1
        while let Some(line) = line_iterator.next() {
79
            lines.push(line.clone());
80
        }
81

            
82
1
        assert!(lines.is_empty());
83
1
    }
84

            
85
    #[test]
86
1
    fn test_line_iterator_single_line() {
87
1
        let data = "single line";
88
1
        let cursor = Cursor::new(data);
89
1
        let mut line_iterator = LineIterator::new(cursor);
90
1

            
91
1
        let mut lines = Vec::new();
92
2
        while let Some(line) = line_iterator.next() {
93
1
            lines.push(line.clone());
94
1
        }
95

            
96
1
        assert_eq!(lines, vec!["single line"]);
97
1
    }
98

            
99
    #[test]
100
1
    fn test_line_iterator_with_carriage_return() {
101
1
        let data = "line1\r\nline2\r\nline3";
102
1
        let cursor = Cursor::new(data);
103
1
        let mut line_iterator = LineIterator::new(cursor);
104
1

            
105
1
        let mut lines = Vec::new();
106
4
        while let Some(line) = line_iterator.next() {
107
3
            lines.push(line.clone());
108
3
        }
109

            
110
1
        assert_eq!(lines, vec!["line1", "line2", "line3"]);
111
1
    }
112
}