/build/cargo-vendor-dir/anstyle-parse-0.2.6/src/state/definitions.rs
Line | Count | Source |
1 | | #![allow(clippy::exhaustive_enums)] |
2 | | |
3 | | use core::mem; |
4 | | |
5 | | #[derive(Debug, Copy, Clone, PartialEq, Eq)] |
6 | | #[repr(u8)] |
7 | | #[derive(Default)] |
8 | | pub 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 | | |
28 | | impl TryFrom<u8> for State { |
29 | | type Error = u8; |
30 | | |
31 | | #[inline(always)] |
32 | 0 | fn try_from(raw: u8) -> Result<Self, Self::Error> { |
33 | 0 | STATES.get(raw as usize).ok_or(raw).copied() |
34 | 0 | } |
35 | | } |
36 | | |
37 | | const 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(Debug, Clone, Copy, PartialEq, Eq)] |
57 | | #[repr(u8)] |
58 | | #[derive(Default)] |
59 | | pub 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 | | |
79 | | impl TryFrom<u8> for Action { |
80 | | type Error = u8; |
81 | | |
82 | | #[inline(always)] |
83 | 0 | fn try_from(raw: u8) -> Result<Self, Self::Error> { |
84 | 0 | ACTIONS.get(raw as usize).ok_or(raw).copied() |
85 | 0 | } |
86 | | } |
87 | | |
88 | | const 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)] |
115 | 0 | pub(crate) const fn unpack(delta: u8) -> (State, Action) { |
116 | 0 | unsafe { |
117 | 0 | ( |
118 | 0 | // State is stored in bottom 4 bits |
119 | 0 | mem::transmute::<u8, State>(delta & 0x0f), |
120 | 0 | // Action is stored in top 4 bits |
121 | 0 | mem::transmute::<u8, Action>(delta >> 4), |
122 | 0 | ) |
123 | 0 | } |
124 | 0 | } |
125 | | |
126 | | #[inline(always)] |
127 | | #[cfg(test)] |
128 | | pub(crate) const fn pack(state: State, action: Action) -> u8 { |
129 | | (action as u8) << 4 | state as u8 |
130 | | } |
131 | | |
132 | | #[cfg(test)] |
133 | | mod 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 | | } |