rustc_proc_macro/
escape.rs

1#[derive(#[automatically_derived]
impl ::core::marker::Copy for EscapeOptions { }Copy, #[automatically_derived]
impl ::core::clone::Clone for EscapeOptions {
    #[inline]
    fn clone(&self) -> EscapeOptions {
        let _: ::core::clone::AssertParamIsClone<bool>;
        *self
    }
}Clone)]
2pub(crate) struct EscapeOptions {
3    /// Produce \'.
4    pub escape_single_quote: bool,
5    /// Produce \".
6    pub escape_double_quote: bool,
7    /// Produce \x escapes for non-ASCII, and use \x rather than \u for ASCII
8    /// control characters.
9    pub escape_nonascii: bool,
10}
11
12pub(crate) fn escape_bytes(bytes: &[u8], opt: EscapeOptions) -> String {
13    let mut repr = String::new();
14
15    if opt.escape_nonascii {
16        for &byte in bytes {
17            escape_single_byte(byte, opt, &mut repr);
18        }
19    } else {
20        for chunk in bytes.utf8_chunks() {
21            for ch in chunk.valid().chars() {
22                escape_single_char(ch, opt, &mut repr);
23            }
24            for &byte in chunk.invalid() {
25                escape_single_byte(byte, opt, &mut repr);
26            }
27        }
28    }
29
30    repr
31}
32
33fn escape_single_byte(byte: u8, opt: EscapeOptions, repr: &mut String) {
34    if byte == b'\0' {
35        repr.push_str("\\0");
36    } else if (byte == b'\'' && !opt.escape_single_quote)
37        || (byte == b'"' && !opt.escape_double_quote)
38    {
39        repr.push(byte as char);
40    } else {
41        // Escapes \t, \r, \n, \\, \', \", and uses \x## for non-ASCII and
42        // for ASCII control characters.
43        repr.extend(byte.escape_ascii().map(char::from));
44    }
45}
46
47fn escape_single_char(ch: char, opt: EscapeOptions, repr: &mut String) {
48    if (ch == '\'' && !opt.escape_single_quote) || (ch == '"' && !opt.escape_double_quote) {
49        repr.push(ch);
50    } else {
51        // Escapes \0, \t, \r, \n, \\, \', \", and uses \u{...} for
52        // non-printable characters and for Grapheme_Extend characters, which
53        // includes things like U+0300 "Combining Grave Accent".
54        repr.extend(ch.escape_debug());
55    }
56}