@@ -2,10 +2,11 @@ use std::str::Chars;
2
2
3
3
/// Peekable iterator over a char sequence.
4
4
///
5
- /// Next characters can be peeked via `nth_char ` method,
5
+ /// Next characters can be peeked via `first ` method,
6
6
/// and position can be shifted forward via `bump` method.
7
7
pub ( crate ) struct Cursor < ' a > {
8
8
initial_len : usize ,
9
+ /// Iterator over chars. Slightly faster than a &str.
9
10
chars : Chars < ' a > ,
10
11
#[ cfg( debug_assertions) ]
11
12
prev : char ,
@@ -37,22 +38,21 @@ impl<'a> Cursor<'a> {
37
38
}
38
39
}
39
40
40
- /// Returns nth character relative to the current cursor position .
41
+ /// Peeks the next symbol from the input stream without consuming it .
41
42
/// If requested position doesn't exist, `EOF_CHAR` is returned.
42
43
/// However, getting `EOF_CHAR` doesn't always mean actual end of file,
43
44
/// it should be checked with `is_eof` method.
44
- fn nth_char ( & self , n : usize ) -> char {
45
- self . chars ( ) . nth ( n) . unwrap_or ( EOF_CHAR )
46
- }
47
-
48
- /// Peeks the next symbol from the input stream without consuming it.
49
45
pub ( crate ) fn first ( & self ) -> char {
50
- self . nth_char ( 0 )
46
+ // `.next()` optimizes better than `.nth(0)`
47
+ self . chars . clone ( ) . next ( ) . unwrap_or ( EOF_CHAR )
51
48
}
52
49
53
50
/// Peeks the second symbol from the input stream without consuming it.
54
51
pub ( crate ) fn second ( & self ) -> char {
55
- self . nth_char ( 1 )
52
+ // `.next()` optimizes better than `.nth(1)`
53
+ let mut iter = self . chars . clone ( ) ;
54
+ iter. next ( ) ;
55
+ iter. next ( ) . unwrap_or ( EOF_CHAR )
56
56
}
57
57
58
58
/// Checks if there is nothing more to consume.
@@ -65,9 +65,9 @@ impl<'a> Cursor<'a> {
65
65
self . initial_len - self . chars . as_str ( ) . len ( )
66
66
}
67
67
68
- /// Returns a `Chars` iterator over the remaining characters .
69
- fn chars ( & self ) -> Chars < ' a > {
70
- self . chars . clone ( )
68
+ /// Resets the number of bytes consumed to 0 .
69
+ pub ( crate ) fn reset_len_consumed ( & mut self ) {
70
+ self . initial_len = self . chars . as_str ( ) . len ( ) ;
71
71
}
72
72
73
73
/// Moves to the next character.
@@ -81,4 +81,13 @@ impl<'a> Cursor<'a> {
81
81
82
82
Some ( c)
83
83
}
84
+
85
+ /// Eats symbols while predicate returns true or until the end of file is reached.
86
+ pub ( crate ) fn eat_while ( & mut self , mut predicate : impl FnMut ( char ) -> bool ) {
87
+ // It was tried making optimized version of this for eg. line comments, but
88
+ // LLVM can inline all of this and compile it down to fast iteration over bytes.
89
+ while predicate ( self . first ( ) ) && !self . is_eof ( ) {
90
+ self . bump ( ) ;
91
+ }
92
+ }
84
93
}
0 commit comments