aboutsummaryrefslogtreecommitdiff
path: root/crates/libsyntax2/src/lexer/ptr.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/libsyntax2/src/lexer/ptr.rs')
-rw-r--r--crates/libsyntax2/src/lexer/ptr.rs42
1 files changed, 28 insertions, 14 deletions
diff --git a/crates/libsyntax2/src/lexer/ptr.rs b/crates/libsyntax2/src/lexer/ptr.rs
index d1391fd5f..aa59e33cc 100644
--- a/crates/libsyntax2/src/lexer/ptr.rs
+++ b/crates/libsyntax2/src/lexer/ptr.rs
@@ -2,12 +2,14 @@ use TextUnit;
2 2
3use std::str::Chars; 3use std::str::Chars;
4 4
5/// A simple view into the characters of a string.
5pub(crate) struct Ptr<'s> { 6pub(crate) struct Ptr<'s> {
6 text: &'s str, 7 text: &'s str,
7 len: TextUnit, 8 len: TextUnit,
8} 9}
9 10
10impl<'s> Ptr<'s> { 11impl<'s> Ptr<'s> {
12 /// Creates a new `Ptr` from a string.
11 pub fn new(text: &'s str) -> Ptr<'s> { 13 pub fn new(text: &'s str) -> Ptr<'s> {
12 Ptr { 14 Ptr {
13 text, 15 text,
@@ -15,45 +17,55 @@ impl<'s> Ptr<'s> {
15 } 17 }
16 } 18 }
17 19
20 /// Gets the length of the remaining string.
18 pub fn into_len(self) -> TextUnit { 21 pub fn into_len(self) -> TextUnit {
19 self.len 22 self.len
20 } 23 }
21 24
22 pub fn next(&self) -> Option<char> { 25 /// Gets the current character, if one exists.
26 pub fn current(&self) -> Option<char> {
23 self.chars().next() 27 self.chars().next()
24 } 28 }
25 29
26 pub fn nnext(&self) -> Option<char> { 30 /// Gets the nth character from the current.
27 let mut chars = self.chars(); 31 /// For example, 0 will return the current token, 1 will return the next, etc.
28 chars.next()?; 32 pub fn nth(&self, n: u32) -> Option<char> {
29 chars.next() 33 let mut chars = self.chars().peekable();
34 chars.by_ref().skip(n as usize).next()
30 } 35 }
31 36
32 pub fn next_is(&self, c: char) -> bool { 37 /// Checks whether the current character is `c`.
33 self.next() == Some(c) 38 pub fn at(&self, c: char) -> bool {
39 self.current() == Some(c)
34 } 40 }
35 41
36 pub fn nnext_is(&self, c: char) -> bool { 42 /// Checks whether the next characters match `s`.
37 self.nnext() == Some(c) 43 pub fn at_str(&self, s: &str) -> bool {
44 let chars = self.chars();
45 chars.as_str().starts_with(s)
38 } 46 }
39 47
40 pub fn next_is_p<P: Fn(char) -> bool>(&self, p: P) -> bool { 48 /// Checks whether the current character satisfies the predicate `p`.
41 self.next().map(p) == Some(true) 49 pub fn at_p<P: Fn(char) -> bool>(&self, p: P) -> bool {
50 self.current().map(p) == Some(true)
42 } 51 }
43 52
44 pub fn nnext_is_p<P: Fn(char) -> bool>(&self, p: P) -> bool { 53 /// Checks whether the nth character satisfies the predicate `p`.
45 self.nnext().map(p) == Some(true) 54 pub fn nth_is_p<P: Fn(char) -> bool>(&self, n: u32, p: P) -> bool {
55 self.nth(n).map(p) == Some(true)
46 } 56 }
47 57
58 /// Moves to the next character.
48 pub fn bump(&mut self) -> Option<char> { 59 pub fn bump(&mut self) -> Option<char> {
49 let ch = self.chars().next()?; 60 let ch = self.chars().next()?;
50 self.len += TextUnit::of_char(ch); 61 self.len += TextUnit::of_char(ch);
51 Some(ch) 62 Some(ch)
52 } 63 }
53 64
65 /// Moves to the next character as long as `pred` is satisfied.
54 pub fn bump_while<F: Fn(char) -> bool>(&mut self, pred: F) { 66 pub fn bump_while<F: Fn(char) -> bool>(&mut self, pred: F) {
55 loop { 67 loop {
56 match self.next() { 68 match self.current() {
57 Some(c) if pred(c) => { 69 Some(c) if pred(c) => {
58 self.bump(); 70 self.bump();
59 } 71 }
@@ -62,11 +74,13 @@ impl<'s> Ptr<'s> {
62 } 74 }
63 } 75 }
64 76
77 /// Returns the text up to the current point.
65 pub fn current_token_text(&self) -> &str { 78 pub fn current_token_text(&self) -> &str {
66 let len: u32 = self.len.into(); 79 let len: u32 = self.len.into();
67 &self.text[..len as usize] 80 &self.text[..len as usize]
68 } 81 }
69 82
83 /// Returns an iterator over the remaining characters.
70 fn chars(&self) -> Chars { 84 fn chars(&self) -> Chars {
71 let len: u32 = self.len.into(); 85 let len: u32 = self.len.into();
72 self.text[len as usize..].chars() 86 self.text[len as usize..].chars()