use crate::Tape;
#[derive(Copy, Clone)]
struct CharType(u8);
impl CharType {
const IS_SIMPLE_WS: Self = Self(0b0100);
const FLAGS_LEN: u32 = 1;
#[inline]
const fn bits(self) -> u8 {
self.0
}
#[inline]
const fn with_len(self, len: u8) -> u8 {
self.0 | (len << Self::FLAGS_LEN)
}
}
const CHAR_TABLE: [u8; 256] = {
let mut table = [0u8; 256];
table[b' ' as usize] = CharType::IS_SIMPLE_WS.with_len(1);
table[b'\t' as usize] = CharType::IS_SIMPLE_WS.with_len(4);
table[b'\r' as usize] = CharType::IS_SIMPLE_WS.with_len(1);
table
};
pub trait CharExt {
#[must_use]
#[allow(clippy::wrong_self_convention)] fn is_simple_ws(self) -> bool;
#[must_use]
fn simple_ws_len(self) -> u8;
}
impl CharExt for u8 {
#[inline]
fn is_simple_ws(self) -> bool {
(CHAR_TABLE[self as usize] & CharType::IS_SIMPLE_WS.bits()) != 0
}
#[inline]
fn simple_ws_len(self) -> u8 {
CHAR_TABLE[self as usize] >> CharType::FLAGS_LEN
}
}
pub trait SliceExt<'a, T> {
fn trim_simple_ws(self) -> Self;
}
impl<'a> SliceExt<'a, u8> for &'a [u8] {
fn trim_simple_ws(mut self) -> Self {
while let [first, rest @ ..] = self {
if first.is_simple_ws() {
self = rest;
} else {
break;
}
}
while let [rest @ .., last] = self {
if last.is_simple_ws() {
self = rest;
} else {
break;
}
}
self
}
}
pub trait ToTape<'a, T> {
fn to_tape(self) -> Tape<'a, T>;
}
impl<'a, T> ToTape<'a, T> for &'a [T] {
fn to_tape(self) -> Tape<'a, T> {
Tape::new(self)
}
}