1use std::collections::HashMap;
2
3use once_cell::sync::Lazy;
4
5#[allow(dead_code)]
6#[derive(PartialEq, Clone, Hash, Eq)]
7pub enum KeyCode {
8 Escape,
9 F1,
10 F2,
11 F3,
12 F4,
13 F5,
14 F6,
15 F7,
16 F8,
17 F9,
18 F10,
19 F11,
20 F12,
21 Backtick,
22 Tilde,
23 Num1,
24 ExclamationPoint,
25 Num2,
26 At,
27 Num3,
28 Hashtag,
29 Num4,
30 Dollar,
31 Num5,
32 Percent,
33 Num6,
34 Caret,
35 Num7,
36 Ampersand,
37 Num8,
38 Asterisks,
39 Num9,
40 OpenParenthesis,
41 Num0,
42 CloseParenthesis,
43 Minus,
44 Underscore,
45 Equals,
46 Plus,
47 Backspace,
48 Tab,
49 Q,
50 W,
51 E,
52 R,
53 T,
54 Y,
55 U,
56 I,
57 O,
58 P,
59 OpenBracket,
60 OpenBrace,
61 CloseBracket,
62 CloseBrace,
63 Backslash,
64 Pipe,
65 CapsLock,
66 A,
67 S,
68 D,
69 F,
70 G,
71 H,
72 J,
73 K,
74 L,
75 SemiColon,
76 Colon,
77 Apostrophe,
78 Quote,
79 Return,
80 LShift,
81 Z,
82 X,
83 C,
84 V,
85 B,
86 N,
87 M,
88 Comma,
89 LessThan,
90 Period,
91 GreaterThan,
92 ForwardSlash,
93 QuestionMark,
94 RShift,
95 LFunction,
96 LControl,
97 LOption,
98 LWindows,
99 LCommand,
100 Space,
101 RAlt,
102 LAlt,
103 RCommand,
104 RWindows,
105 ROption,
106 RFunction,
107 RControl,
108
109 Insert,
110 Delete,
111 Home,
112 End,
113 PageUp,
114 PageDown,
115
116 UpArrow,
117 DownArrow,
118 LeftArrow,
119 RightArrow,
120}
121
122static KEY_STRING_MAP: Lazy<HashMap<KeyCode, &str>> = Lazy::new(|| {
123 HashMap::from([
124 (KeyCode::Escape, "Escape"),
125 (KeyCode::F1, "F1"),
126 (KeyCode::F2, "F2"),
127 (KeyCode::F3, "F3"),
128 (KeyCode::F4, "F4"),
129 (KeyCode::F5, "F5"),
130 (KeyCode::F6, "F6"),
131 (KeyCode::F7, "F7"),
132 (KeyCode::F8, "F8"),
133 (KeyCode::F9, "F9"),
134 (KeyCode::F10, "F10"),
135 (KeyCode::F11, "F11"),
136 (KeyCode::F12, "F12"),
137 (KeyCode::Backtick, "`"),
138 (KeyCode::Tilde, "~"),
139 (KeyCode::Num1, "1"),
140 (KeyCode::ExclamationPoint, "!"),
141 (KeyCode::Num2, "2"),
142 (KeyCode::At, "@"),
143 (KeyCode::Num3, "3"),
144 (KeyCode::Hashtag, "#"),
145 (KeyCode::Num4, "4"),
146 (KeyCode::Dollar, "$"),
147 (KeyCode::Num5, "5"),
148 (KeyCode::Percent, "%"),
149 (KeyCode::Num6, "6"),
150 (KeyCode::Caret, "^"),
151 (KeyCode::Num7, "7"),
152 (KeyCode::Ampersand, "&"),
153 (KeyCode::Num8, "8"),
154 (KeyCode::Asterisks, "*"),
155 (KeyCode::Num9, "9"),
156 (KeyCode::OpenParenthesis, "("),
157 (KeyCode::Num0, "0"),
158 (KeyCode::CloseParenthesis, ")"),
159 (KeyCode::Minus, "-"),
160 (KeyCode::Underscore, "_"),
161 (KeyCode::Equals, "="),
162 (KeyCode::Plus, "+"),
163 (KeyCode::Backspace, "Backspace"),
164 (KeyCode::Tab, "Tab"),
165 (KeyCode::Q, "Q"),
166 (KeyCode::W, "W"),
167 (KeyCode::E, "E"),
168 (KeyCode::R, "R"),
169 (KeyCode::T, "T"),
170 (KeyCode::Y, "Y"),
171 (KeyCode::U, "U"),
172 (KeyCode::I, "I"),
173 (KeyCode::O, "O"),
174 (KeyCode::P, "P"),
175 (KeyCode::OpenBracket, "["),
176 (KeyCode::OpenBrace, "{"),
177 (KeyCode::CloseBracket, "]"),
178 (KeyCode::CloseBrace, "}"),
179 (KeyCode::Backslash, "\\"),
180 (KeyCode::Pipe, "|"),
181 (KeyCode::CapsLock, "CapsLock"),
182 (KeyCode::A, "A"),
183 (KeyCode::S, "S"),
184 (KeyCode::D, "D"),
185 (KeyCode::F, "F"),
186 (KeyCode::G, "G"),
187 (KeyCode::H, "H"),
188 (KeyCode::J, "J"),
189 (KeyCode::K, "K"),
190 (KeyCode::L, "L"),
191 (KeyCode::SemiColon, ";"),
192 (KeyCode::Colon, ":"),
193 (KeyCode::Apostrophe, "'"),
194 (KeyCode::Quote, "\""),
195 (KeyCode::Return, "Return"),
196 (KeyCode::LShift, "LShift"),
197 (KeyCode::Z, "Z"),
198 (KeyCode::X, "X"),
199 (KeyCode::C, "C"),
200 (KeyCode::V, "V"),
201 (KeyCode::B, "B"),
202 (KeyCode::N, "N"),
203 (KeyCode::M, "M"),
204 (KeyCode::Comma, "),"),
205 (KeyCode::LessThan, "<"),
206 (KeyCode::Period, "."),
207 (KeyCode::GreaterThan, ">"),
208 (KeyCode::ForwardSlash, "/"),
209 (KeyCode::QuestionMark, "?"),
210 (KeyCode::RShift, "RShift"),
211 (KeyCode::LFunction, "LFunction"),
212 (KeyCode::LControl, "LControl"),
213 (KeyCode::LOption, "LOption"),
214 (KeyCode::LWindows, "LWindows"),
215 (KeyCode::LCommand, "LCommand"),
216 (KeyCode::Space, "Space"),
217 (KeyCode::RAlt, "RAlt"),
218 (KeyCode::LAlt, "LAlt"),
219 (KeyCode::RCommand, "RCommand"),
220 (KeyCode::RWindows, "RWindows"),
221 (KeyCode::ROption, "ROption"),
222 (KeyCode::RFunction, "RFunction"),
223 (KeyCode::RControl, "RControl"),
224 (KeyCode::Insert, "Insert"),
225 (KeyCode::Delete, "Delete"),
226 (KeyCode::Home, "Home"),
227 (KeyCode::End, "End"),
228 (KeyCode::PageUp, "PageUp"),
229 (KeyCode::PageDown, "PageDown"),
230 (KeyCode::UpArrow, "UpArrow"),
231 (KeyCode::DownArrow, "DownArrow"),
232 (KeyCode::LeftArrow, "LeftArrow"),
233 (KeyCode::RightArrow, "RightArrow"),
234 ])
235});
236
237impl KeyCode {
238 pub fn serialize(&self) -> String {
239 KEY_STRING_MAP[self].to_string()
240 }
241
242 pub fn deserialize(data: String) -> Result<Option<Self>, ()> {
243 let mut result: Result<Option<Self>, ()> = Err(());
244
245 if data == "..." {
246 return Ok(None);
247 }
248
249 for (key, str) in KEY_STRING_MAP.iter() {
250 if str.eq_ignore_ascii_case(data.as_str()) {
251 result = Ok(Some(key.clone()));
252 break;
253 }
254 }
255
256 result
257 }
258}
259
260impl From<device_query::Keycode> for KeyCode {
261 fn from(item: device_query::Keycode) -> KeyCode {
262 match item {
263 device_query::Keycode::Key0 => KeyCode::Num0,
264 device_query::Keycode::Key1 => KeyCode::Num1,
265 device_query::Keycode::Key2 => KeyCode::Num2,
266 device_query::Keycode::Key3 => KeyCode::Num3,
267 device_query::Keycode::Key4 => KeyCode::Num4,
268 device_query::Keycode::Key5 => KeyCode::Num5,
269 device_query::Keycode::Key6 => KeyCode::Num6,
270 device_query::Keycode::Key7 => KeyCode::Num7,
271 device_query::Keycode::Key8 => KeyCode::Num8,
272 device_query::Keycode::Key9 => KeyCode::Num9,
273 device_query::Keycode::A => KeyCode::A,
274 device_query::Keycode::B => KeyCode::B,
275 device_query::Keycode::C => KeyCode::C,
276 device_query::Keycode::D => KeyCode::D,
277 device_query::Keycode::E => KeyCode::E,
278 device_query::Keycode::F => KeyCode::F,
279 device_query::Keycode::G => KeyCode::G,
280 device_query::Keycode::H => KeyCode::H,
281 device_query::Keycode::I => KeyCode::I,
282 device_query::Keycode::J => KeyCode::J,
283 device_query::Keycode::K => KeyCode::K,
284 device_query::Keycode::L => KeyCode::L,
285 device_query::Keycode::M => KeyCode::M,
286 device_query::Keycode::N => KeyCode::N,
287 device_query::Keycode::O => KeyCode::O,
288 device_query::Keycode::P => KeyCode::P,
289 device_query::Keycode::Q => KeyCode::Q,
290 device_query::Keycode::R => KeyCode::R,
291 device_query::Keycode::S => KeyCode::S,
292 device_query::Keycode::T => KeyCode::T,
293 device_query::Keycode::U => KeyCode::U,
294 device_query::Keycode::V => KeyCode::V,
295 device_query::Keycode::W => KeyCode::W,
296 device_query::Keycode::X => KeyCode::X,
297 device_query::Keycode::Y => KeyCode::Y,
298 device_query::Keycode::Z => KeyCode::Z,
299 device_query::Keycode::F1 => KeyCode::F1,
300 device_query::Keycode::F2 => KeyCode::F2,
301 device_query::Keycode::F3 => KeyCode::F3,
302 device_query::Keycode::F4 => KeyCode::F4,
303 device_query::Keycode::F5 => KeyCode::F5,
304 device_query::Keycode::F6 => KeyCode::F6,
305 device_query::Keycode::F7 => KeyCode::F7,
306 device_query::Keycode::F8 => KeyCode::F8,
307 device_query::Keycode::F9 => KeyCode::F9,
308 device_query::Keycode::F10 => KeyCode::F10,
309 device_query::Keycode::F11 => KeyCode::F11,
310 device_query::Keycode::F12 => KeyCode::F12,
311 device_query::Keycode::Escape => KeyCode::Escape,
312 device_query::Keycode::Space => KeyCode::Space,
313 device_query::Keycode::LControl => KeyCode::LControl,
314 device_query::Keycode::RControl => KeyCode::RControl,
315 device_query::Keycode::LShift => KeyCode::LShift,
316 device_query::Keycode::RShift => KeyCode::RShift,
317 device_query::Keycode::LAlt => KeyCode::LAlt,
318 device_query::Keycode::RAlt => KeyCode::RAlt,
319 device_query::Keycode::Meta => KeyCode::LWindows, device_query::Keycode::Enter => KeyCode::Return,
321 device_query::Keycode::Up => KeyCode::UpArrow,
322 device_query::Keycode::Down => KeyCode::DownArrow,
323 device_query::Keycode::Left => KeyCode::LeftArrow,
324 device_query::Keycode::Right => KeyCode::RightArrow,
325 device_query::Keycode::Backspace => KeyCode::Backspace,
326 device_query::Keycode::CapsLock => KeyCode::CapsLock,
327 device_query::Keycode::Tab => KeyCode::Tab,
328 device_query::Keycode::Home => KeyCode::Home,
329 device_query::Keycode::End => KeyCode::End,
330 device_query::Keycode::PageUp => KeyCode::PageUp,
331 device_query::Keycode::PageDown => KeyCode::PageDown,
332 device_query::Keycode::Insert => KeyCode::Insert,
333 device_query::Keycode::Delete => KeyCode::Delete,
334 device_query::Keycode::Numpad0 => KeyCode::Num0,
335 device_query::Keycode::Numpad1 => KeyCode::Num1,
336 device_query::Keycode::Numpad2 => KeyCode::Num2,
337 device_query::Keycode::Numpad3 => KeyCode::Num3,
338 device_query::Keycode::Numpad4 => KeyCode::Num4,
339 device_query::Keycode::Numpad5 => KeyCode::Num5,
340 device_query::Keycode::Numpad6 => KeyCode::Num6,
341 device_query::Keycode::Numpad7 => KeyCode::Num7,
342 device_query::Keycode::Numpad8 => KeyCode::Num8,
343 device_query::Keycode::Numpad9 => KeyCode::Num9,
344 device_query::Keycode::NumpadSubtract => KeyCode::Minus,
345 device_query::Keycode::NumpadAdd => KeyCode::Plus,
346 device_query::Keycode::NumpadDivide => KeyCode::ForwardSlash,
347 device_query::Keycode::NumpadMultiply => KeyCode::Asterisks,
348 device_query::Keycode::Grave => KeyCode::Backtick,
349 device_query::Keycode::Minus => KeyCode::Minus,
350 device_query::Keycode::Equal => KeyCode::Equals,
351 device_query::Keycode::LeftBracket => KeyCode::OpenBracket,
352 device_query::Keycode::RightBracket => KeyCode::CloseBracket,
353 device_query::Keycode::BackSlash => KeyCode::Backslash,
354 device_query::Keycode::Semicolon => KeyCode::SemiColon,
355 device_query::Keycode::Apostrophe => KeyCode::Apostrophe,
356 device_query::Keycode::Comma => KeyCode::Comma,
357 device_query::Keycode::Dot => KeyCode::Period,
358 device_query::Keycode::Slash => KeyCode::ForwardSlash,
359 }
360 }
361}
362
363impl KeyCode {
364 pub fn as_modifier(&self) -> Option<KeyModifier> {
365 return match self {
366 KeyCode::LControl => Some(KeyModifier::CtrlCmd),
367 KeyCode::RControl => Some(KeyModifier::CtrlCmd),
368 KeyCode::RAlt => Some(KeyModifier::AltOpt),
369 KeyCode::LAlt => Some(KeyModifier::AltOpt),
370 KeyCode::LOption => Some(KeyModifier::AltOpt),
371 KeyCode::ROption => Some(KeyModifier::AltOpt),
372 KeyCode::LCommand => Some(KeyModifier::CtrlCmd),
373 KeyCode::RCommand => Some(KeyModifier::CtrlCmd),
374 KeyCode::LWindows => Some(KeyModifier::CtrlCmd),
375 KeyCode::RWindows => Some(KeyModifier::CtrlCmd),
376 KeyCode::LFunction => Some(KeyModifier::Function),
377 KeyCode::RFunction => Some(KeyModifier::Function),
378 KeyCode::LShift => Some(KeyModifier::Shift),
379 KeyCode::RShift => Some(KeyModifier::Shift),
380 _ => None,
381 };
382 }
383}
384
385#[derive(PartialEq, Clone, PartialOrd, Eq, Ord, Hash)]
387pub enum KeyModifier {
388 CtrlCmd = 1, AltOpt = 2, Shift = 3, Function = 4, }
393
394impl KeyModifier {
395 pub fn serialize(&self) -> char {
396 match self {
397 KeyModifier::CtrlCmd => '^',
398 KeyModifier::Shift => '_',
399 KeyModifier::AltOpt => '*',
400 KeyModifier::Function => '~',
401 }
402 }
403
404 pub fn deserialize(data: char) -> Result<Self, ()> {
405 match data {
406 '^' => Ok(KeyModifier::CtrlCmd),
407 '_' => Ok(KeyModifier::Shift),
408 '*' => Ok(KeyModifier::AltOpt),
409 '~' => Ok(KeyModifier::Function),
410 _ => Err(()),
411 }
412 }
413}