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

Function normalize_string

crates/ruff_python_formatter/src/string/normalize.rs:664–767  ·  view source on GitHub ↗
(
    input: &str,
    start_offset: usize,
    new_flags: AnyStringFlags,
    escape_braces: bool,
)

Source from the content-addressed store, hash-verified

662}
663
664pub(crate) fn normalize_string(
665 input: &str,
666 start_offset: usize,
667 new_flags: AnyStringFlags,
668 escape_braces: bool,
669) -> Cow<'_, str> {
670 // The normalized string if `input` is not yet normalized.
671 // `output` must remain empty if `input` is already normalized.
672 let mut output = String::new();
673 // Tracks the last index of `input` that has been written to `output`.
674 // If `last_index` is `0` at the end, then the input is already normalized and can be returned as is.
675 let mut last_index = 0;
676
677 let quote = new_flags.quote_style();
678 let preferred_quote = quote.as_char();
679 let opposite_quote = quote.opposite().as_char();
680
681 let mut chars = CharIndicesWithOffset::new(input, start_offset).peekable();
682
683 let is_raw = new_flags.is_raw_string();
684
685 while let Some((index, c)) = chars.next() {
686 if matches!(c, '{' | '}') {
687 if escape_braces {
688 // Escape `{` and `}` when converting a regular string literal to an f-string literal.
689 output.push_str(&input[last_index..=index]);
690 output.push(c);
691 last_index = index + c.len_utf8();
692 continue;
693 }
694 }
695
696 if c == '\r' {
697 output.push_str(&input[last_index..index]);
698
699 // Skip over the '\r' character, keep the `\n`
700 if chars.peek().copied().is_some_and(|(_, next)| next == '\n') {
701 chars.next();
702 }
703 // Replace the `\r` with a `\n`
704 else {
705 output.push('\n');
706 }
707
708 last_index = index + '\r'.len_utf8();
709 } else if !is_raw {
710 if c == '\\' {
711 if let Some((_, next)) = chars.clone().next() {
712 if next == '\\' {
713 // Skip over escaped backslashes
714 chars.next();
715 } else {
716 // Length of the `\` plus the length of the escape sequence character (`u` | `U` | `x`)
717 let escape_start_len = '\\'.len_utf8() + next.len_utf8();
718 if let Some(normalised) =
719 UnicodeEscape::new(next, !new_flags.is_byte_string()).and_then(
720 |escape| escape.normalize(&input[index + escape_start_len..]),
721 )

Callers 4

normalizeMethod · 0.85
fmtMethod · 0.85
fmtMethod · 0.85

Calls 15

len_utf8Method · 0.80
and_thenMethod · 0.80
is_byte_stringMethod · 0.80
quote_styleMethod · 0.45
as_charMethod · 0.45
oppositeMethod · 0.45
is_raw_stringMethod · 0.45
nextMethod · 0.45
push_strMethod · 0.45
pushMethod · 0.45
peekMethod · 0.45
cloneMethod · 0.45

Tested by 1