pub(super) type ByteHandler = Option<for<'aa> fn(&mut SkipWhitespace<'aa>) -> u32>;
static BYTE_HANDLERS: [ByteHandler; 256] = [
___, ___, ___, ___, ___, ___, ___, ___, ___, SPC, NLN, SPC, SPC, NLN, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, SPC, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, ___, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, UNI, ];
const ___: ByteHandler = None;
const NLN: ByteHandler = Some(|skip| {
skip.newline = true;
1
});
const SPC: ByteHandler = Some(|_| 1);
const UNI: ByteHandler = Some(|skip| {
let s = unsafe {
skip.input.get_unchecked(skip.offset as usize..)
};
let c = unsafe {
s.chars().next().unwrap_unchecked()
};
match c {
'\u{feff}' => {}
'\u{2028}' | '\u{2029}' => {
skip.newline = true;
}
_ if c.is_whitespace() => {}
_ => return 0,
}
c.len_utf8() as u32
});
pub(super) struct SkipWhitespace<'a> {
pub input: &'a str,
pub offset: u32,
pub newline: bool,
}
impl SkipWhitespace<'_> {
#[inline(always)]
pub fn scan(&mut self) {
let mut byte;
loop {
byte = match self.input.as_bytes().get(self.offset as usize).copied() {
Some(v) => v,
None => return,
};
let handler = unsafe { *(&BYTE_HANDLERS as *const ByteHandler).offset(byte as isize) };
if let Some(handler) = handler {
let delta = handler(self);
if delta == 0 {
return;
}
self.offset += delta;
} else {
return;
}
}
}
}