Skip to main content

anstyle_parse/state/
definitions.rs

1#![allow(clippy::exhaustive_enums)]
2
3use core::mem;
4
5#[derive(#[automatically_derived]
impl ::core::fmt::Debug for State {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                State::Anywhere => "Anywhere",
                State::CsiEntry => "CsiEntry",
                State::CsiIgnore => "CsiIgnore",
                State::CsiIntermediate => "CsiIntermediate",
                State::CsiParam => "CsiParam",
                State::DcsEntry => "DcsEntry",
                State::DcsIgnore => "DcsIgnore",
                State::DcsIntermediate => "DcsIntermediate",
                State::DcsParam => "DcsParam",
                State::DcsPassthrough => "DcsPassthrough",
                State::Escape => "Escape",
                State::EscapeIntermediate => "EscapeIntermediate",
                State::Ground => "Ground",
                State::OscString => "OscString",
                State::SosPmApcString => "SosPmApcString",
                State::Utf8 => "Utf8",
            })
    }
}Debug, #[automatically_derived]
impl ::core::marker::Copy for State { }Copy, #[automatically_derived]
impl ::core::clone::Clone for State {
    #[inline]
    fn clone(&self) -> State { *self }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for State {
    #[inline]
    fn eq(&self, other: &State) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for State {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
6#[repr(u8)]
7#[derive(#[automatically_derived]
impl ::core::default::Default for State {
    #[inline]
    fn default() -> State { Self::Ground }
}Default)]
8pub enum State {
9    Anywhere = 0,
10    CsiEntry = 1,
11    CsiIgnore = 2,
12    CsiIntermediate = 3,
13    CsiParam = 4,
14    DcsEntry = 5,
15    DcsIgnore = 6,
16    DcsIntermediate = 7,
17    DcsParam = 8,
18    DcsPassthrough = 9,
19    Escape = 10,
20    EscapeIntermediate = 11,
21    #[default]
22    Ground = 12,
23    OscString = 13,
24    SosPmApcString = 14,
25    Utf8 = 15,
26}
27
28impl TryFrom<u8> for State {
29    type Error = u8;
30
31    #[inline(always)]
32    fn try_from(raw: u8) -> Result<Self, Self::Error> {
33        STATES.get(raw as usize).ok_or(raw).copied()
34    }
35}
36
37const STATES: [State; 16] = [
38    State::Anywhere,
39    State::CsiEntry,
40    State::CsiIgnore,
41    State::CsiIntermediate,
42    State::CsiParam,
43    State::DcsEntry,
44    State::DcsIgnore,
45    State::DcsIntermediate,
46    State::DcsParam,
47    State::DcsPassthrough,
48    State::Escape,
49    State::EscapeIntermediate,
50    State::Ground,
51    State::OscString,
52    State::SosPmApcString,
53    State::Utf8,
54];
55
56#[derive(#[automatically_derived]
impl ::core::fmt::Debug for Action {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::write_str(f,
            match self {
                Action::Nop => "Nop",
                Action::Clear => "Clear",
                Action::Collect => "Collect",
                Action::CsiDispatch => "CsiDispatch",
                Action::EscDispatch => "EscDispatch",
                Action::Execute => "Execute",
                Action::Hook => "Hook",
                Action::Ignore => "Ignore",
                Action::OscEnd => "OscEnd",
                Action::OscPut => "OscPut",
                Action::OscStart => "OscStart",
                Action::Param => "Param",
                Action::Print => "Print",
                Action::Put => "Put",
                Action::Unhook => "Unhook",
                Action::BeginUtf8 => "BeginUtf8",
            })
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for Action {
    #[inline]
    fn clone(&self) -> Action { *self }
}Clone, #[automatically_derived]
impl ::core::marker::Copy for Action { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for Action {
    #[inline]
    fn eq(&self, other: &Action) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr
    }
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for Action {
    #[inline]
    #[doc(hidden)]
    #[coverage(off)]
    fn assert_fields_are_eq(&self) {}
}Eq)]
57#[repr(u8)]
58#[derive(#[automatically_derived]
impl ::core::default::Default for Action {
    #[inline]
    fn default() -> Action { Self::Nop }
}Default)]
59pub enum Action {
60    #[default]
61    Nop = 0,
62    Clear = 1,
63    Collect = 2,
64    CsiDispatch = 3,
65    EscDispatch = 4,
66    Execute = 5,
67    Hook = 6,
68    Ignore = 7,
69    OscEnd = 8,
70    OscPut = 9,
71    OscStart = 10,
72    Param = 11,
73    Print = 12,
74    Put = 13,
75    Unhook = 14,
76    BeginUtf8 = 15,
77}
78
79impl TryFrom<u8> for Action {
80    type Error = u8;
81
82    #[inline(always)]
83    fn try_from(raw: u8) -> Result<Self, Self::Error> {
84        ACTIONS.get(raw as usize).ok_or(raw).copied()
85    }
86}
87
88const ACTIONS: [Action; 16] = [
89    Action::Nop,
90    Action::Clear,
91    Action::Collect,
92    Action::CsiDispatch,
93    Action::EscDispatch,
94    Action::Execute,
95    Action::Hook,
96    Action::Ignore,
97    Action::OscEnd,
98    Action::OscPut,
99    Action::OscStart,
100    Action::Param,
101    Action::Print,
102    Action::Put,
103    Action::Unhook,
104    Action::BeginUtf8,
105];
106
107/// Unpack a u8 into a State and Action
108///
109/// The implementation of this assumes that there are *precisely* 16 variants for both Action and
110/// State. Furthermore, it assumes that the enums are tag-only; that is, there is no data in any
111/// variant.
112///
113/// Bad things will happen if those invariants are violated.
114#[inline(always)]
115pub(crate) const fn unpack(delta: u8) -> (State, Action) {
116    unsafe {
117        (
118            // State is stored in bottom 4 bits
119            mem::transmute::<u8, State>(delta & 0x0f),
120            // Action is stored in top 4 bits
121            mem::transmute::<u8, Action>(delta >> 4),
122        )
123    }
124}
125
126#[inline(always)]
127#[cfg(test)]
128pub(crate) const fn pack(state: State, action: Action) -> u8 {
129    ((action as u8) << 4) | state as u8
130}
131
132#[cfg(test)]
133mod tests {
134    use super::*;
135
136    #[test]
137    fn unpack_state_action() {
138        match unpack(0xee) {
139            (State::SosPmApcString, Action::Unhook) => (),
140            _ => panic!("unpack failed"),
141        }
142
143        match unpack(0x0f) {
144            (State::Utf8, Action::Nop) => (),
145            _ => panic!("unpack failed"),
146        }
147
148        match unpack(0xff) {
149            (State::Utf8, Action::BeginUtf8) => (),
150            _ => panic!("unpack failed"),
151        }
152    }
153
154    #[test]
155    fn pack_state_action() {
156        match unpack(0xee) {
157            (State::SosPmApcString, Action::Unhook) => (),
158            _ => panic!("unpack failed"),
159        }
160
161        match unpack(0x0f) {
162            (State::Utf8, Action::Nop) => (),
163            _ => panic!("unpack failed"),
164        }
165
166        match unpack(0xff) {
167            (State::Utf8, Action::BeginUtf8) => (),
168            _ => panic!("unpack failed"),
169        }
170    }
171}