(mut self)
| 374 | } |
| 375 | |
| 376 | fn parse_bytes(mut self) -> Result<StringType, LexicalError> { |
| 377 | if let Some(index) = self.source.as_bytes().find_non_ascii_byte() { |
| 378 | let ch = self.source.chars().nth(index).unwrap(); |
| 379 | return Err(LexicalError::new( |
| 380 | LexicalErrorType::InvalidByteLiteral, |
| 381 | TextRange::at( |
| 382 | self.compute_position(index), |
| 383 | TextSize::try_from(ch.len_utf8()).unwrap(), |
| 384 | ), |
| 385 | )); |
| 386 | } |
| 387 | |
| 388 | if self.flags.is_raw_string() { |
| 389 | // For raw strings, no escaping is necessary. |
| 390 | return Ok(StringType::Bytes(ast::BytesLiteral { |
| 391 | value: self.source.as_bytes().into(), |
| 392 | range: self.range, |
| 393 | flags: self.flags.into(), |
| 394 | node_index: AtomicNodeIndex::NONE, |
| 395 | })); |
| 396 | } |
| 397 | |
| 398 | let Some(mut escape) = memchr::memchr(b'\\', self.source.as_bytes()) else { |
| 399 | // If the string doesn't contain any escape sequences, return the owned string. |
| 400 | return Ok(StringType::Bytes(ast::BytesLiteral { |
| 401 | value: self.source.as_bytes().into(), |
| 402 | range: self.range, |
| 403 | flags: self.flags.into(), |
| 404 | node_index: AtomicNodeIndex::NONE, |
| 405 | })); |
| 406 | }; |
| 407 | |
| 408 | // If the string contains escape sequences, we need to parse them. |
| 409 | let mut value = Vec::with_capacity(self.source.len()); |
| 410 | loop { |
| 411 | // Add the characters before the escape sequence to the string. |
| 412 | let before_with_slash = self.skip_bytes(escape + 1); |
| 413 | let before = &before_with_slash[..before_with_slash.len() - 1]; |
| 414 | value.extend_from_slice(before.as_bytes()); |
| 415 | |
| 416 | // Add the escaped character to the string. |
| 417 | match self.parse_escaped_char()? { |
| 418 | None => {} |
| 419 | Some(EscapedChar::Literal(c)) => value.push(c as u8), |
| 420 | Some(EscapedChar::Escape(c)) => { |
| 421 | value.push(b'\\'); |
| 422 | value.push(c as u8); |
| 423 | } |
| 424 | } |
| 425 | |
| 426 | let Some(next_escape) = memchr::memchr(b'\\', &self.source.as_bytes()[self.cursor..]) |
| 427 | else { |
| 428 | // Add the rest of the string to the value. |
| 429 | let rest = &self.source[self.cursor..]; |
| 430 | value.extend_from_slice(rest.as_bytes()); |
| 431 | break; |
| 432 | }; |
| 433 |
no test coverage detected