(mut self)
| 318 | } |
| 319 | |
| 320 | fn parse_bytes(mut self) -> Result<StringType, LexicalError> { |
| 321 | if let Some(index) = self.source.as_bytes().find_non_ascii_byte() { |
| 322 | let ch = self.source.chars().nth(index).unwrap(); |
| 323 | return Err(LexicalError::new( |
| 324 | LexicalErrorType::InvalidByteLiteral, |
| 325 | TextRange::at( |
| 326 | self.compute_position(index), |
| 327 | TextSize::try_from(ch.len_utf8()).unwrap(), |
| 328 | ), |
| 329 | )); |
| 330 | } |
| 331 | |
| 332 | if self.flags.is_raw_string() { |
| 333 | // For raw strings, no escaping is necessary. |
| 334 | return Ok(StringType::Bytes(ast::BytesLiteral { |
| 335 | value: self.source.into_boxed_bytes(), |
| 336 | range: self.range, |
| 337 | flags: self.flags.into(), |
| 338 | })); |
| 339 | } |
| 340 | |
| 341 | let Some(mut escape) = memchr::memchr(b'\\', self.source.as_bytes()) else { |
| 342 | // If the string doesn't contain any escape sequences, return the owned string. |
| 343 | return Ok(StringType::Bytes(ast::BytesLiteral { |
| 344 | value: self.source.into_boxed_bytes(), |
| 345 | range: self.range, |
| 346 | flags: self.flags.into(), |
| 347 | })); |
| 348 | }; |
| 349 | |
| 350 | // If the string contains escape sequences, we need to parse them. |
| 351 | let mut value = Vec::with_capacity(self.source.len()); |
| 352 | loop { |
| 353 | // Add the characters before the escape sequence to the string. |
| 354 | let before_with_slash = self.skip_bytes(escape + 1); |
| 355 | let before = &before_with_slash[..before_with_slash.len() - 1]; |
| 356 | value.extend_from_slice(before.as_bytes()); |
| 357 | |
| 358 | // Add the escaped character to the string. |
| 359 | match self.parse_escaped_char()? { |
| 360 | None => {} |
| 361 | Some(EscapedChar::Literal(c)) => value.push(c as u8), |
| 362 | Some(EscapedChar::Escape(c)) => { |
| 363 | value.push(b'\\'); |
| 364 | value.push(c as u8); |
| 365 | } |
| 366 | } |
| 367 | |
| 368 | let Some(next_escape) = memchr::memchr(b'\\', self.source[self.cursor..].as_bytes()) |
| 369 | else { |
| 370 | // Add the rest of the string to the value. |
| 371 | let rest = &self.source[self.cursor..]; |
| 372 | value.extend_from_slice(rest.as_bytes()); |
| 373 | break; |
| 374 | }; |
| 375 | |
| 376 | // Update the position of the next escape sequence. |
| 377 | escape = next_escape; |
no test coverage detected