(&mut self)
| 173 | } |
| 174 | |
| 175 | fn parse_string(&mut self) -> Result<Token<'a>, ParseError> { |
| 176 | let quote = self.bytes[self.byte_index]; |
| 177 | let start = self.byte_index + 1; |
| 178 | |
| 179 | // fast path: scan for closing quote or backslash byte-by-byte. |
| 180 | // this is safe because quote (0x22/0x27) and backslash (0x5C) are ASCII |
| 181 | // and can never appear as continuation bytes in multi-byte UTF-8 sequences. |
| 182 | let mut i = start; |
| 183 | while i < self.bytes.len() { |
| 184 | let b = self.bytes[i]; |
| 185 | if b == quote { |
| 186 | // found closing quote with no escapes |
| 187 | let s = &self.file_text[start..i]; |
| 188 | self.byte_index = i + 1; |
| 189 | return Ok(Token::String(Cow::Borrowed(s))); |
| 190 | } |
| 191 | if b == b'\\' { |
| 192 | break; |
| 193 | } |
| 194 | i += 1; |
| 195 | } |
| 196 | |
| 197 | // slow path: handle escape sequences via CharProvider |
| 198 | crate::string::parse_string_with_char_provider(self) |
| 199 | .map(Token::String) |
| 200 | // todo(dsherret): don't convert the error kind to a string here |
| 201 | .map_err(|err| self.create_error_for_start(err.byte_index, ParseErrorKind::String(err.kind))) |
| 202 | } |
| 203 | |
| 204 | fn parse_number(&mut self) -> Result<Token<'a>, ParseError> { |
| 205 | let start_byte_index = self.byte_index; |
no test coverage detected