#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
pub(crate) enum ByteClass {
Other,
Bang,
Dollar,
Amp,
LParen,
RParen,
Comma,
Colon,
Eq,
At,
LBracket,
RBracket,
LCurly,
RCurly,
Pipe,
Name,
Zero,
Digit,
Quote,
Hash,
Dot,
Minus,
Whitespace,
Bom,
}
static BYTE_CLASS: [ByteClass; 256] = byte_class_lut();
#[inline]
pub(crate) fn byte_class(c: u8) -> ByteClass {
BYTE_CLASS[c as usize]
}
#[inline]
pub(crate) fn is_namestart(c: u8) -> bool {
matches!(byte_class(c), ByteClass::Name)
}
const fn byte_class_lut() -> [ByteClass; 256] {
let mut lut = [ByteClass::Other; 256];
lut[b'!' as usize] = ByteClass::Bang;
lut[b'$' as usize] = ByteClass::Dollar;
lut[b'&' as usize] = ByteClass::Amp;
lut[b'(' as usize] = ByteClass::LParen;
lut[b')' as usize] = ByteClass::RParen;
lut[b',' as usize] = ByteClass::Comma;
lut[b':' as usize] = ByteClass::Colon;
lut[b'=' as usize] = ByteClass::Eq;
lut[b'@' as usize] = ByteClass::At;
lut[b'[' as usize] = ByteClass::LBracket;
lut[b']' as usize] = ByteClass::RBracket;
lut[b'{' as usize] = ByteClass::LCurly;
lut[b'}' as usize] = ByteClass::RCurly;
lut[b'|' as usize] = ByteClass::Pipe;
let mut c = b'a';
while c <= b'z' {
lut[c as usize] = ByteClass::Name;
c += 1;
}
let mut c = b'A';
while c <= b'Z' {
lut[c as usize] = ByteClass::Name;
c += 1;
}
lut[b'_' as usize] = ByteClass::Name;
lut[b'0' as usize] = ByteClass::Zero;
let mut c = b'1';
while c <= b'9' {
lut[c as usize] = ByteClass::Digit;
c += 1;
}
lut[b'"' as usize] = ByteClass::Quote;
lut[b'#' as usize] = ByteClass::Hash;
lut[b'.' as usize] = ByteClass::Dot;
lut[b'-' as usize] = ByteClass::Minus;
lut[b'\t' as usize] = ByteClass::Whitespace;
lut[b' ' as usize] = ByteClass::Whitespace;
lut[b'\n' as usize] = ByteClass::Whitespace;
lut[b'\r' as usize] = ByteClass::Whitespace;
lut[0xEF] = ByteClass::Bom;
lut
}