Line | Count | Source (jump to first uncovered line) |
1 | | use crate::io; |
2 | | |
3 | | pub struct LineColIterator<I> { |
4 | | iter: I, |
5 | | |
6 | | /// Index of the current line. Characters in the first line of the input |
7 | | /// (before the first newline character) are in line 1. |
8 | | line: usize, |
9 | | |
10 | | /// Index of the current column. The first character in the input and any |
11 | | /// characters immediately following a newline character are in column 1. |
12 | | /// The column is 0 immediately after a newline character has been read. |
13 | | col: usize, |
14 | | |
15 | | /// Byte offset of the start of the current line. This is the sum of lengths |
16 | | /// of all previous lines. Keeping track of things this way allows efficient |
17 | | /// computation of the current line, column, and byte offset while only |
18 | | /// updating one of the counters in `next()` in the common case. |
19 | | start_of_line: usize, |
20 | | } |
21 | | |
22 | | impl<I> LineColIterator<I> |
23 | | where |
24 | | I: Iterator<Item = io::Result<u8>>, |
25 | | { |
26 | 0 | pub fn new(iter: I) -> LineColIterator<I> { |
27 | 0 | LineColIterator { |
28 | 0 | iter, |
29 | 0 | line: 1, |
30 | 0 | col: 0, |
31 | 0 | start_of_line: 0, |
32 | 0 | } |
33 | 0 | } |
34 | | |
35 | 0 | pub fn line(&self) -> usize { |
36 | 0 | self.line |
37 | 0 | } |
38 | | |
39 | 0 | pub fn col(&self) -> usize { |
40 | 0 | self.col |
41 | 0 | } |
42 | | |
43 | 0 | pub fn byte_offset(&self) -> usize { |
44 | 0 | self.start_of_line + self.col |
45 | 0 | } |
46 | | } |
47 | | |
48 | | impl<I> Iterator for LineColIterator<I> |
49 | | where |
50 | | I: Iterator<Item = io::Result<u8>>, |
51 | | { |
52 | | type Item = io::Result<u8>; |
53 | | |
54 | 0 | fn next(&mut self) -> Option<io::Result<u8>> { |
55 | 0 | match self.iter.next() { |
56 | 0 | None => None, |
57 | | Some(Ok(b'\n')) => { |
58 | 0 | self.start_of_line += self.col + 1; |
59 | 0 | self.line += 1; |
60 | 0 | self.col = 0; |
61 | 0 | Some(Ok(b'\n')) |
62 | | } |
63 | 0 | Some(Ok(c)) => { |
64 | 0 | self.col += 1; |
65 | 0 | Some(Ok(c)) |
66 | | } |
67 | 0 | Some(Err(e)) => Some(Err(e)), |
68 | | } |
69 | 0 | } |
70 | | } |