summaryrefslogtreecommitdiff
path: root/vendor/anstyle-parse/src/state/definitions.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/anstyle-parse/src/state/definitions.rs')
-rw-r--r--vendor/anstyle-parse/src/state/definitions.rs169
1 files changed, 169 insertions, 0 deletions
diff --git a/vendor/anstyle-parse/src/state/definitions.rs b/vendor/anstyle-parse/src/state/definitions.rs
new file mode 100644
index 0000000..c4e7673
--- /dev/null
+++ b/vendor/anstyle-parse/src/state/definitions.rs
@@ -0,0 +1,169 @@
+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,
+];
+
+/// 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 const 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)]
+#[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"),
+ }
+ }
+}