MCPcopy Create free account
hub / github.com/astral-sh/ruff / parse_bytes

Method parse_bytes

crates/ruff_python_parser/src/string.rs:376–444  ·  view source on GitHub ↗
(mut self)

Source from the content-addressed store, hash-verified

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

Callers 1

parseMethod · 0.80

Calls 13

OkClass · 0.85
BytesClass · 0.85
compute_positionMethod · 0.80
len_utf8Method · 0.80
extend_from_sliceMethod · 0.80
parse_escaped_charMethod · 0.80
as_bytesMethod · 0.45
charsMethod · 0.45
is_raw_stringMethod · 0.45
lenMethod · 0.45
skip_bytesMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected