use core::mem;
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
#[repr(u8)]
#[derive(Default)]
pub enum State {
Anywhere = 0,
CsiEntry = 1,
CsiIgnore = 2,
CsiIntermediate = 3,
CsiParam = 4,
DcsEntry = 5,
DcsIgnore = 6,
DcsIntermediate = 7,
DcsParam = 8,
DcsPassthrough = 9,
Escape = 10,
EscapeIntermediate = 11,
#[default]
Ground = 12,
OscString = 13,
SosPmApcString = 14,
Utf8 = 15,
}
impl TryFrom<u8> for State {
type Error = u8;
#[inline(always)]
fn try_from(raw: u8) -> Result<Self, Self::Error> {
STATES.get(raw as usize).ok_or(raw).copied()
}
}
const STATES: [State; 16] = [
State::Anywhere,
State::CsiEntry,
State::CsiIgnore,
State::CsiIntermediate,
State::CsiParam,
State::DcsEntry,
State::DcsIgnore,
State::DcsIntermediate,
State::DcsParam,
State::DcsPassthrough,
State::Escape,
State::EscapeIntermediate,
State::Ground,
State::OscString,
State::SosPmApcString,
State::Utf8,
];
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u8)]
#[derive(Default)]
pub enum Action {
#[default]
Nop = 0,
Clear = 1,
Collect = 2,
CsiDispatch = 3,
EscDispatch = 4,
Execute = 5,
Hook = 6,
Ignore = 7,
OscEnd = 8,
OscPut = 9,
OscStart = 10,
Param = 11,
Print = 12,
Put = 13,
Unhook = 14,
BeginUtf8 = 15,
}
impl TryFrom<u8> for Action {
type Error = u8;
#[inline(always)]
fn try_from(raw: u8) -> Result<Self, Self::Error> {
ACTIONS.get(raw as usize).ok_or(raw).copied()
}
}
const ACTIONS: [Action; 16] = [
Action::Nop,
Action::Clear,
Action::Collect,
Action::CsiDispatch,
Action::EscDispatch,
Action::Execute,
Action::Hook,
Action::Ignore,
Action::OscEnd,
Action::OscPut,
Action::OscStart,
Action::Param,
Action::Print,
Action::Put,
Action::Unhook,
Action::BeginUtf8,
];
#[inline(always)]
pub const fn unpack(delta: u8) -> (State, Action) {
unsafe {
(
mem::transmute(delta & 0x0f),
mem::transmute(delta >> 4),
)
}
}
#[inline(always)]
#[cfg(test)]
pub const fn pack(state: State, action: Action) -> u8 {
(action as u8) << 4 | state as u8
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn unpack_state_action() {
match unpack(0xee) {
(State::SosPmApcString, Action::Unhook) => (),
_ => panic!("unpack failed"),
}
match unpack(0x0f) {
(State::Utf8, Action::Nop) => (),
_ => panic!("unpack failed"),
}
match unpack(0xff) {
(State::Utf8, Action::BeginUtf8) => (),
_ => panic!("unpack failed"),
}
}
#[test]
fn pack_state_action() {
match unpack(0xee) {
(State::SosPmApcString, Action::Unhook) => (),
_ => panic!("unpack failed"),
}
match unpack(0x0f) {
(State::Utf8, Action::Nop) => (),
_ => panic!("unpack failed"),
}
match unpack(0xff) {
(State::Utf8, Action::BeginUtf8) => (),
_ => panic!("unpack failed"),
}
}
}