rustc_ast/util/
unicode.rs

1pub const TEXT_FLOW_CONTROL_CHARS: &[char] = &[
2    '\u{202A}', '\u{202B}', '\u{202D}', '\u{202E}', '\u{2066}', '\u{2067}', '\u{2068}', '\u{202C}',
3    '\u{2069}',
4];
5
6#[inline]
7pub fn contains_text_flow_control_chars(s: &str) -> bool {
8    // Char   - UTF-8
9    // U+202A - E2 80 AA
10    // U+202B - E2 80 AB
11    // U+202C - E2 80 AC
12    // U+202D - E2 80 AD
13    // U+202E - E2 80 AE
14    // U+2066 - E2 81 A6
15    // U+2067 - E2 81 A7
16    // U+2068 - E2 81 A8
17    // U+2069 - E2 81 A9
18    let mut bytes = s.as_bytes();
19    loop {
20        match memchr::memchr(0xE2, bytes) {
21            Some(idx) => {
22                // bytes are valid UTF-8 -> E2 must be followed by two bytes
23                let ch = &bytes[idx..idx + 3];
24                match ch {
25                    [_, 0x80, 0xAA..=0xAE] | [_, 0x81, 0xA6..=0xA9] => break true,
26                    _ => {}
27                }
28                bytes = &bytes[idx + 3..];
29            }
30            None => {
31                break false;
32            }
33        }
34    }
35}