const_panic/
debug_str_fmt.rs

1// most of this copied from const_format, which is mine, but still..
2
3#[doc(hidden)]
4pub(crate) struct ForEscaping {
5    pub(crate) is_escaped: u128,
6    pub(crate) is_backslash_escaped: u128,
7    pub(crate) escape_char: [u8; 16],
8}
9
10impl ForEscaping {
11    /// Gets the backslash escape for a character that is kwown to be escaped with a backslash.
12    #[inline(always)]
13    pub(crate) const fn get_backslash_escape(b: u8) -> u8 {
14        FOR_ESCAPING.escape_char[(b & 0b1111) as usize]
15    }
16
17    // how long this byte inside a utf8 string takes to represent in debug formatting.
18    pub(crate) const fn byte_len(c: u8) -> usize {
19        if c < 128 {
20            let shifted = 1 << c;
21
22            if (FOR_ESCAPING.is_escaped & shifted) != 0 {
23                if (FOR_ESCAPING.is_backslash_escaped & shifted) != 0 {
24                    2
25                } else {
26                    4
27                }
28            } else {
29                1
30            }
31        } else {
32            1
33        }
34    }
35
36    pub(crate) const fn is_escaped(c: u8) -> bool {
37        (c < 128) && ((FOR_ESCAPING.is_escaped & (1 << c)) != 0)
38    }
39
40    pub(crate) const fn is_backslash_escaped(c: u8) -> bool {
41        (c < 128) && ((FOR_ESCAPING.is_backslash_escaped & (1 << c)) != 0)
42    }
43}
44
45#[doc(hidden)]
46/// Converts 0..=0xF to its ascii representation of '0'..='9' and 'A'..='F'
47#[inline(always)]
48pub(crate) const fn hex_as_ascii(n: u8) -> u8 {
49    if n < 10 {
50        n + b'0'
51    } else {
52        n - 10 + b'A'
53    }
54}
55
56#[doc(hidden)]
57pub(crate) const FOR_ESCAPING: &ForEscaping = {
58    let mut is_backslash_escaped = 0;
59
60    let escaped = [
61        (b'\t', b't'),
62        (b'\n', b'n'),
63        (b'\r', b'r'),
64        (b'\'', b'\''),
65        (b'"', b'"'),
66        (b'\\', b'\\'),
67    ];
68
69    // Using the fact that the characters above all have different bit patterns for
70    // the lowest 4 bits.
71    let mut escape_char = [0u8; 16];
72
73    let escaped_len = escaped.len();
74    let mut i = 0;
75    while i < escaped_len {
76        let (code, escape) = escaped[i];
77        is_backslash_escaped |= 1 << code;
78
79        let ei = (code & 0b1111) as usize;
80        if escape_char[ei] != 0 {
81            panic!("Oh no, some escaped character uses the same 4 lower bits as another")
82        }
83        escape_char[ei] = escape;
84        i += 1;
85    }
86
87    // Setting all the control characters as being escaped.
88    let is_escaped = is_backslash_escaped | 0xFFFF_FFFF;
89
90    &ForEscaping {
91        escape_char,
92        is_backslash_escaped,
93        is_escaped,
94    }
95};