| use core::mem; |
| |
| #[allow(dead_code)] |
| #[derive(Debug, Copy, Clone)] |
| 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, |
| Ground = 12, |
| OscString = 13, |
| SosPmApcString = 14, |
| Utf8 = 15, |
| } |
| |
| impl Default for State { |
| fn default() -> State { |
| State::Ground |
| } |
| } |
| |
| #[allow(dead_code)] |
| #[derive(Debug, Clone, Copy)] |
| pub enum Action { |
| None = 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, |
| } |
| |
| /// Unpack a u8 into a State and Action |
| /// |
| /// The implementation of this assumes that there are *precisely* 16 variants for both Action and |
| /// State. Furthermore, it assumes that the enums are tag-only; that is, there is no data in any |
| /// variant. |
| /// |
| /// Bad things will happen if those invariants are violated. |
| #[inline(always)] |
| pub fn unpack(delta: u8) -> (State, Action) { |
| unsafe { |
| ( |
| // State is stored in bottom 4 bits |
| mem::transmute(delta & 0x0f), |
| // Action is stored in top 4 bits |
| mem::transmute(delta >> 4), |
| ) |
| } |
| } |
| |
| #[inline(always)] |
| 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::None) => (), |
| _ => 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::None) => (), |
| _ => panic!("unpack failed"), |
| } |
| |
| match unpack(0xff) { |
| (State::Utf8, Action::BeginUtf8) => (), |
| _ => panic!("unpack failed"), |
| } |
| } |
| } |