@@ -2,10 +2,11 @@ use std::str::Chars;
22
33/// Peekable iterator over a char sequence.
44///
5- /// Next characters can be peeked via `nth_char ` method,
5+ /// Next characters can be peeked via `first ` method,
66/// and position can be shifted forward via `bump` method.
77pub ( crate ) struct Cursor < ' a > {
88 initial_len : usize ,
9+ /// Iterator over chars. Slightly faster than a &str.
910 chars : Chars < ' a > ,
1011 #[ cfg( debug_assertions) ]
1112 prev : char ,
@@ -37,22 +38,21 @@ impl<'a> Cursor<'a> {
3738 }
3839 }
3940
40- /// Returns nth character relative to the current cursor position .
41+ /// Peeks the next symbol from the input stream without consuming it .
4142 /// If requested position doesn't exist, `EOF_CHAR` is returned.
4243 /// However, getting `EOF_CHAR` doesn't always mean actual end of file,
4344 /// 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.
4945 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 )
5148 }
5249
5350 /// Peeks the second symbol from the input stream without consuming it.
5451 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 )
5656 }
5757
5858 /// Checks if there is nothing more to consume.
@@ -65,9 +65,9 @@ impl<'a> Cursor<'a> {
6565 self . initial_len - self . chars . as_str ( ) . len ( )
6666 }
6767
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 ( ) ;
7171 }
7272
7373 /// Moves to the next character.
@@ -81,4 +81,13 @@ impl<'a> Cursor<'a> {
8181
8282 Some ( c)
8383 }
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+ }
8493}
0 commit comments