1 use super::errors::{ErrorKind, ParserError};
2 use super::{Parser, Result, Slice};
3 
4 impl<'s, S> Parser<S>
5 where
6     S: Slice<'s>,
7 {
is_current_byte(&self, b: u8) -> bool8     pub(super) fn is_current_byte(&self, b: u8) -> bool {
9         self.source.as_ref().as_bytes().get(self.ptr) == Some(&b)
10     }
11 
is_byte_at(&self, b: u8, pos: usize) -> bool12     pub(super) fn is_byte_at(&self, b: u8, pos: usize) -> bool {
13         self.source.as_ref().as_bytes().get(pos) == Some(&b)
14     }
15 
skip_to_next_entry_start(&mut self)16     pub(super) fn skip_to_next_entry_start(&mut self) {
17         while let Some(b) = self.source.as_ref().as_bytes().get(self.ptr) {
18             let new_line =
19                 self.ptr == 0 || self.source.as_ref().as_bytes().get(self.ptr - 1) == Some(&b'\n');
20 
21             if new_line && (b.is_ascii_alphabetic() || [b'-', b'#'].contains(b)) {
22                 break;
23             }
24 
25             self.ptr += 1;
26         }
27     }
28 
skip_eol(&mut self) -> bool29     pub(super) fn skip_eol(&mut self) -> bool {
30         match self.source.as_ref().as_bytes().get(self.ptr) {
31             Some(b'\n') => {
32                 self.ptr += 1;
33                 true
34             }
35             Some(b'\r') if self.is_byte_at(b'\n', self.ptr + 1) => {
36                 self.ptr += 2;
37                 true
38             }
39             _ => false,
40         }
41     }
42 
skip_unicode_escape_sequence(&mut self, length: usize) -> Result<()>43     pub(super) fn skip_unicode_escape_sequence(&mut self, length: usize) -> Result<()> {
44         let start = self.ptr;
45         for _ in 0..length {
46             match self.source.as_ref().as_bytes().get(self.ptr) {
47                 Some(b) if b.is_ascii_hexdigit() => self.ptr += 1,
48                 _ => break,
49             }
50         }
51         if self.ptr - start != length {
52             let end = if self.ptr >= self.length {
53                 self.ptr
54             } else {
55                 self.ptr + 1
56             };
57             let seq = self.source.slice(start..end).as_ref().to_owned();
58             return error!(ErrorKind::InvalidUnicodeEscapeSequence(seq), self.ptr);
59         }
60         Ok(())
61     }
62 
is_identifier_start(&self) -> bool63     pub(super) fn is_identifier_start(&self) -> bool {
64         matches!(self.source.as_ref().as_bytes().get(self.ptr), Some(b) if b.is_ascii_alphabetic())
65     }
66 
take_byte_if(&mut self, b: u8) -> bool67     pub(super) fn take_byte_if(&mut self, b: u8) -> bool {
68         if self.is_current_byte(b) {
69             self.ptr += 1;
70             true
71         } else {
72             false
73         }
74     }
75 
skip_blank_block(&mut self) -> usize76     pub(super) fn skip_blank_block(&mut self) -> usize {
77         let mut count = 0;
78         loop {
79             let start = self.ptr;
80             self.skip_blank_inline();
81             if !self.skip_eol() {
82                 self.ptr = start;
83                 break;
84             }
85             count += 1;
86         }
87         count
88     }
89 
skip_blank(&mut self)90     pub(super) fn skip_blank(&mut self) {
91         loop {
92             match self.source.as_ref().as_bytes().get(self.ptr) {
93                 Some(b' ') | Some(b'\n') => self.ptr += 1,
94                 Some(b'\r')
95                     if self.source.as_ref().as_bytes().get(self.ptr + 1) == Some(&b'\n') =>
96                 {
97                     self.ptr += 2
98                 }
99                 _ => break,
100             }
101         }
102     }
103 
skip_blank_inline(&mut self) -> usize104     pub(super) fn skip_blank_inline(&mut self) -> usize {
105         let start = self.ptr;
106         while let Some(b' ') = self.source.as_ref().as_bytes().get(self.ptr) {
107             self.ptr += 1;
108         }
109         self.ptr - start
110     }
111 
is_byte_pattern_continuation(b: u8) -> bool112     pub(super) fn is_byte_pattern_continuation(b: u8) -> bool {
113         ![b'}', b'.', b'[', b'*'].contains(&b)
114     }
115 
is_callee(name: &[u8]) -> bool116     pub(super) fn is_callee(name: &[u8]) -> bool {
117         name.iter()
118             .all(|c| c.is_ascii_uppercase() || c.is_ascii_digit() || *c == b'_' || *c == b'-')
119     }
120 
expect_byte(&mut self, b: u8) -> Result<()>121     pub(super) fn expect_byte(&mut self, b: u8) -> Result<()> {
122         if !self.is_current_byte(b) {
123             return error!(ErrorKind::ExpectedToken(b as char), self.ptr);
124         }
125         self.ptr += 1;
126         Ok(())
127     }
128 
is_number_start(&self) -> bool129     pub(super) fn is_number_start(&self) -> bool {
130         matches!(self.source.as_ref().as_bytes().get(self.ptr), Some(b) if (b == &b'-') || b.is_ascii_digit())
131     }
132 
is_eol(&self) -> bool133     pub(super) fn is_eol(&self) -> bool {
134         match self.source.as_ref().as_bytes().get(self.ptr) {
135             Some(b'\n') => true,
136             Some(b'\r') if self.is_byte_at(b'\n', self.ptr + 1) => true,
137             _ => false,
138         }
139     }
140 
skip_digits(&mut self) -> Result<()>141     pub(super) fn skip_digits(&mut self) -> Result<()> {
142         let start = self.ptr;
143         loop {
144             match self.source.as_ref().as_bytes().get(self.ptr) {
145                 Some(b) if b.is_ascii_digit() => self.ptr += 1,
146                 _ => break,
147             }
148         }
149         if start == self.ptr {
150             error!(
151                 ErrorKind::ExpectedCharRange {
152                     range: "0-9".to_string()
153                 },
154                 self.ptr
155             )
156         } else {
157             Ok(())
158         }
159     }
160 
get_number_literal(&mut self) -> Result<S>161     pub(super) fn get_number_literal(&mut self) -> Result<S> {
162         let start = self.ptr;
163         self.take_byte_if(b'-');
164         self.skip_digits()?;
165         if self.take_byte_if(b'.') {
166             self.skip_digits()?;
167         }
168 
169         Ok(self.source.slice(start..self.ptr))
170     }
171 }
172