pub struct Parser(State);
#[allow(non_camel_case_types)]
enum State {
Ground = 0,
Tail3 = 1,
Tail2 = 2,
Tail1 = 3,
U3_2_e0 = 4,
U3_2_ed = 5,
Utf8_4_3_f0 = 6,
Utf8_4_3_f4 = 7,
}
impl Parser {
#[inline]
pub fn new() -> Parser {
Parser(State::Ground)
}
#[inline]
pub fn is_expecting(&self) -> bool {
!matches!(self.0, State::Ground)
}
pub fn advance(&mut self, v: u8) -> bool {
let (state, is_invalid) = match self.0 {
State::Ground => match v {
0x00..=0x7f => (State::Ground, false),
0xc2..=0xdf => (State::Tail1, false),
0xe0 => (State::U3_2_e0, false),
0xe1..=0xec => (State::Tail2, false),
0xed => (State::U3_2_ed, false),
0xee..=0xef => (State::Tail2, false),
0xf0 => (State::Utf8_4_3_f0, false),
0xf1..=0xf3 => (State::Tail3, false),
0xf4 => (State::Utf8_4_3_f4, false),
_ => (State::Ground, true),
},
State::U3_2_e0 => match v {
0xa0..=0xbf => (State::Tail1, false),
_ => (State::Ground, true),
},
State::U3_2_ed => match v {
0x80..=0x9f => (State::Tail1, false),
_ => (State::Ground, true),
},
State::Utf8_4_3_f0 => match v {
0x90..=0xbf => (State::Tail2, false),
_ => (State::Ground, true),
},
State::Utf8_4_3_f4 => match v {
0x80..=0x8f => (State::Tail2, false),
_ => (State::Ground, true),
},
State::Tail3 => match v {
0x80..=0xbf => (State::Tail2, false),
_ => (State::Ground, true),
},
State::Tail2 => match v {
0x80..=0xbf => (State::Tail1, false),
_ => (State::Ground, true),
},
State::Tail1 => match v {
0x80..=0xbf => (State::Ground, false),
_ => (State::Ground, true),
},
};
self.0 = state;
is_invalid
}
}