1use std::fmt;
5use std::str::FromStr;
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
11#[repr(i32)]
12pub enum PhysicalKey {
13 #[default]
15 None = 0,
16 Backquote = 1,
19 Backslash = 2,
23 BracketLeft = 3,
25 BracketRight = 4,
27 Comma = 5,
29 Digit0 = 6,
31 Digit1 = 7,
33 Digit2 = 8,
35 Digit3 = 9,
37 Digit4 = 10,
39 Digit5 = 11,
41 Digit6 = 12,
43 Digit7 = 13,
45 Digit8 = 14,
47 Digit9 = 15,
49 Equal = 16,
51 IntlBackslash = 17,
54 IntlRo = 18,
57 IntlYen = 19,
61 A = 20,
64 B = 21,
66 C = 22,
68 D = 23,
70 E = 24,
72 F = 25,
74 G = 26,
76 H = 27,
78 I = 28,
80 J = 29,
82 K = 30,
84 L = 31,
86 M = 32,
88 N = 33,
90 O = 34,
92 P = 35,
94 Q = 36,
97 R = 37,
99 S = 38,
101 T = 39,
103 U = 40,
105 V = 41,
107 W = 42,
110 X = 43,
112 Y = 44,
115 Z = 45,
119 Minus = 46,
121 Period = 47,
123 Quote = 48,
125 Semicolon = 49,
127 Slash = 50,
129 AltLeft = 51,
131 AltRight = 52,
134 Backspace = 53,
137 CapsLock = 54,
139 ContextMenu = 55,
142 ControlLeft = 56,
144 ControlRight = 57,
146 Enter = 58,
149 MetaLeft = 59,
151 MetaRight = 60,
153 ShiftLeft = 61,
155 ShiftRight = 62,
157 Space = 63,
159 Tab = 64,
161 Convert = 65,
163 KanaMode = 66,
165 Lang1 = 67,
168 Lang2 = 68,
171 Lang3 = 69,
173 Lang4 = 70,
175 Lang5 = 71,
177 NonConvert = 72,
179 Delete = 73,
183 End = 74,
185 Help = 75,
188 Home = 76,
190 Insert = 77,
193 PageDown = 78,
195 PageUp = 79,
197 ArrowDown = 80,
199 ArrowLeft = 81,
201 ArrowRight = 82,
203 ArrowUp = 83,
205 NumLock = 84,
208 NumPad0 = 85,
211 NumPad1 = 86,
214 NumPad2 = 87,
217 NumPad3 = 88,
220 NumPad4 = 89,
223 NumPad5 = 90,
226 NumPad6 = 91,
229 NumPad7 = 92,
232 NumPad8 = 93,
235 NumPad9 = 94,
238 NumPadAdd = 95,
240 NumPadClear = 96,
244 NumPadComma = 97,
247 NumPadDecimal = 98,
250 NumPadDivide = 99,
252 NumPadEnter = 100,
254 NumPadEqual = 101,
256 NumPadMultiply = 102,
259 NumPadParenLeft = 103,
262 NumPadParenRight = 104,
265 NumPadSubtract = 105,
267 Escape = 106,
269 F1 = 107,
271 F2 = 108,
273 F3 = 109,
275 F4 = 110,
277 F5 = 111,
279 F6 = 112,
281 F7 = 113,
283 F8 = 114,
285 F9 = 115,
287 F10 = 116,
289 F11 = 117,
291 F12 = 118,
293 F13 = 119,
295 F14 = 120,
297 F15 = 121,
299 F16 = 122,
301 F17 = 123,
303 F18 = 124,
305 F19 = 125,
307 F20 = 126,
309 F21 = 127,
311 F22 = 128,
313 F23 = 129,
315 F24 = 130,
317 PrintScreen = 131,
319 ScrollLock = 132,
321 Pause = 133,
323 BrowserBack = 134,
326 BrowserFavorites = 135,
328 BrowserForward = 136,
331 BrowserHome = 137,
333 BrowserRefresh = 138,
335 BrowserSearch = 139,
337 BrowserStop = 140,
339 Eject = 141,
342 LaunchApp1 = 142,
345 LaunchApp2 = 143,
348 LaunchMail = 144,
350 MediaPlayPause = 145,
352 MediaSelect = 146,
354 MediaStop = 147,
356 MediaTrackNext = 148,
358 MediaTrackPrevious = 149,
360 Power = 150,
362 Sleep = 151,
364 AudioVolumeDown = 152,
366 AudioVolumeMute = 153,
368 AudioVolumeUp = 154,
370 WakeUp = 155,
372 Again = 156,
376 Copy = 157,
380 Cut = 158,
384 Find = 159,
388 Open = 160,
392 Paste = 161,
396 Props = 162,
400 Select = 163,
404 Undo = 164,
408}
409
410#[derive(Clone, Debug, PartialEq, Eq)]
412pub struct ParsePhysicalKeyError(pub String);
413
414impl fmt::Display for ParsePhysicalKeyError {
415 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
416 write!(f, "Requested value '{}' was not found.", self.0)
417 }
418}
419
420impl std::error::Error for ParsePhysicalKeyError {}
421
422static NAMES: &[(&str, PhysicalKey)] = &[
424 ("None", PhysicalKey::None),
425 ("Backquote", PhysicalKey::Backquote),
426 ("Backslash", PhysicalKey::Backslash),
427 ("BracketLeft", PhysicalKey::BracketLeft),
428 ("BracketRight", PhysicalKey::BracketRight),
429 ("Comma", PhysicalKey::Comma),
430 ("Digit0", PhysicalKey::Digit0),
431 ("Digit1", PhysicalKey::Digit1),
432 ("Digit2", PhysicalKey::Digit2),
433 ("Digit3", PhysicalKey::Digit3),
434 ("Digit4", PhysicalKey::Digit4),
435 ("Digit5", PhysicalKey::Digit5),
436 ("Digit6", PhysicalKey::Digit6),
437 ("Digit7", PhysicalKey::Digit7),
438 ("Digit8", PhysicalKey::Digit8),
439 ("Digit9", PhysicalKey::Digit9),
440 ("Equal", PhysicalKey::Equal),
441 ("IntlBackslash", PhysicalKey::IntlBackslash),
442 ("IntlRo", PhysicalKey::IntlRo),
443 ("IntlYen", PhysicalKey::IntlYen),
444 ("A", PhysicalKey::A),
445 ("B", PhysicalKey::B),
446 ("C", PhysicalKey::C),
447 ("D", PhysicalKey::D),
448 ("E", PhysicalKey::E),
449 ("F", PhysicalKey::F),
450 ("G", PhysicalKey::G),
451 ("H", PhysicalKey::H),
452 ("I", PhysicalKey::I),
453 ("J", PhysicalKey::J),
454 ("K", PhysicalKey::K),
455 ("L", PhysicalKey::L),
456 ("M", PhysicalKey::M),
457 ("N", PhysicalKey::N),
458 ("O", PhysicalKey::O),
459 ("P", PhysicalKey::P),
460 ("Q", PhysicalKey::Q),
461 ("R", PhysicalKey::R),
462 ("S", PhysicalKey::S),
463 ("T", PhysicalKey::T),
464 ("U", PhysicalKey::U),
465 ("V", PhysicalKey::V),
466 ("W", PhysicalKey::W),
467 ("X", PhysicalKey::X),
468 ("Y", PhysicalKey::Y),
469 ("Z", PhysicalKey::Z),
470 ("Minus", PhysicalKey::Minus),
471 ("Period", PhysicalKey::Period),
472 ("Quote", PhysicalKey::Quote),
473 ("Semicolon", PhysicalKey::Semicolon),
474 ("Slash", PhysicalKey::Slash),
475 ("AltLeft", PhysicalKey::AltLeft),
476 ("AltRight", PhysicalKey::AltRight),
477 ("Backspace", PhysicalKey::Backspace),
478 ("CapsLock", PhysicalKey::CapsLock),
479 ("ContextMenu", PhysicalKey::ContextMenu),
480 ("ControlLeft", PhysicalKey::ControlLeft),
481 ("ControlRight", PhysicalKey::ControlRight),
482 ("Enter", PhysicalKey::Enter),
483 ("MetaLeft", PhysicalKey::MetaLeft),
484 ("MetaRight", PhysicalKey::MetaRight),
485 ("ShiftLeft", PhysicalKey::ShiftLeft),
486 ("ShiftRight", PhysicalKey::ShiftRight),
487 ("Space", PhysicalKey::Space),
488 ("Tab", PhysicalKey::Tab),
489 ("Convert", PhysicalKey::Convert),
490 ("KanaMode", PhysicalKey::KanaMode),
491 ("Lang1", PhysicalKey::Lang1),
492 ("Lang2", PhysicalKey::Lang2),
493 ("Lang3", PhysicalKey::Lang3),
494 ("Lang4", PhysicalKey::Lang4),
495 ("Lang5", PhysicalKey::Lang5),
496 ("NonConvert", PhysicalKey::NonConvert),
497 ("Delete", PhysicalKey::Delete),
498 ("End", PhysicalKey::End),
499 ("Help", PhysicalKey::Help),
500 ("Home", PhysicalKey::Home),
501 ("Insert", PhysicalKey::Insert),
502 ("PageDown", PhysicalKey::PageDown),
503 ("PageUp", PhysicalKey::PageUp),
504 ("ArrowDown", PhysicalKey::ArrowDown),
505 ("ArrowLeft", PhysicalKey::ArrowLeft),
506 ("ArrowRight", PhysicalKey::ArrowRight),
507 ("ArrowUp", PhysicalKey::ArrowUp),
508 ("NumLock", PhysicalKey::NumLock),
509 ("NumPad0", PhysicalKey::NumPad0),
510 ("NumPad1", PhysicalKey::NumPad1),
511 ("NumPad2", PhysicalKey::NumPad2),
512 ("NumPad3", PhysicalKey::NumPad3),
513 ("NumPad4", PhysicalKey::NumPad4),
514 ("NumPad5", PhysicalKey::NumPad5),
515 ("NumPad6", PhysicalKey::NumPad6),
516 ("NumPad7", PhysicalKey::NumPad7),
517 ("NumPad8", PhysicalKey::NumPad8),
518 ("NumPad9", PhysicalKey::NumPad9),
519 ("NumPadAdd", PhysicalKey::NumPadAdd),
520 ("NumPadClear", PhysicalKey::NumPadClear),
521 ("NumPadComma", PhysicalKey::NumPadComma),
522 ("NumPadDecimal", PhysicalKey::NumPadDecimal),
523 ("NumPadDivide", PhysicalKey::NumPadDivide),
524 ("NumPadEnter", PhysicalKey::NumPadEnter),
525 ("NumPadEqual", PhysicalKey::NumPadEqual),
526 ("NumPadMultiply", PhysicalKey::NumPadMultiply),
527 ("NumPadParenLeft", PhysicalKey::NumPadParenLeft),
528 ("NumPadParenRight", PhysicalKey::NumPadParenRight),
529 ("NumPadSubtract", PhysicalKey::NumPadSubtract),
530 ("Escape", PhysicalKey::Escape),
531 ("F1", PhysicalKey::F1),
532 ("F2", PhysicalKey::F2),
533 ("F3", PhysicalKey::F3),
534 ("F4", PhysicalKey::F4),
535 ("F5", PhysicalKey::F5),
536 ("F6", PhysicalKey::F6),
537 ("F7", PhysicalKey::F7),
538 ("F8", PhysicalKey::F8),
539 ("F9", PhysicalKey::F9),
540 ("F10", PhysicalKey::F10),
541 ("F11", PhysicalKey::F11),
542 ("F12", PhysicalKey::F12),
543 ("F13", PhysicalKey::F13),
544 ("F14", PhysicalKey::F14),
545 ("F15", PhysicalKey::F15),
546 ("F16", PhysicalKey::F16),
547 ("F17", PhysicalKey::F17),
548 ("F18", PhysicalKey::F18),
549 ("F19", PhysicalKey::F19),
550 ("F20", PhysicalKey::F20),
551 ("F21", PhysicalKey::F21),
552 ("F22", PhysicalKey::F22),
553 ("F23", PhysicalKey::F23),
554 ("F24", PhysicalKey::F24),
555 ("PrintScreen", PhysicalKey::PrintScreen),
556 ("ScrollLock", PhysicalKey::ScrollLock),
557 ("Pause", PhysicalKey::Pause),
558 ("BrowserBack", PhysicalKey::BrowserBack),
559 ("BrowserFavorites", PhysicalKey::BrowserFavorites),
560 ("BrowserForward", PhysicalKey::BrowserForward),
561 ("BrowserHome", PhysicalKey::BrowserHome),
562 ("BrowserRefresh", PhysicalKey::BrowserRefresh),
563 ("BrowserSearch", PhysicalKey::BrowserSearch),
564 ("BrowserStop", PhysicalKey::BrowserStop),
565 ("Eject", PhysicalKey::Eject),
566 ("LaunchApp1", PhysicalKey::LaunchApp1),
567 ("LaunchApp2", PhysicalKey::LaunchApp2),
568 ("LaunchMail", PhysicalKey::LaunchMail),
569 ("MediaPlayPause", PhysicalKey::MediaPlayPause),
570 ("MediaSelect", PhysicalKey::MediaSelect),
571 ("MediaStop", PhysicalKey::MediaStop),
572 ("MediaTrackNext", PhysicalKey::MediaTrackNext),
573 ("MediaTrackPrevious", PhysicalKey::MediaTrackPrevious),
574 ("Power", PhysicalKey::Power),
575 ("Sleep", PhysicalKey::Sleep),
576 ("AudioVolumeDown", PhysicalKey::AudioVolumeDown),
577 ("AudioVolumeMute", PhysicalKey::AudioVolumeMute),
578 ("AudioVolumeUp", PhysicalKey::AudioVolumeUp),
579 ("WakeUp", PhysicalKey::WakeUp),
580 ("Again", PhysicalKey::Again),
581 ("Copy", PhysicalKey::Copy),
582 ("Cut", PhysicalKey::Cut),
583 ("Find", PhysicalKey::Find),
584 ("Open", PhysicalKey::Open),
585 ("Paste", PhysicalKey::Paste),
586 ("Props", PhysicalKey::Props),
587 ("Select", PhysicalKey::Select),
588 ("Undo", PhysicalKey::Undo),
589];
590
591#[allow(non_upper_case_globals)]
592impl PhysicalKey {
593 #[inline]
595 pub const fn value(self) -> i32 {
596 self as i32
597 }
598
599 pub fn from_value(value: i32) -> Option<PhysicalKey> {
601 NAMES.iter().map(|(_, k)| *k).find(|k| *k as i32 == value)
602 }
603
604 pub fn name(self) -> &'static str {
607 match self {
608 PhysicalKey::None => "None",
609 PhysicalKey::Backquote => "Backquote",
610 PhysicalKey::Backslash => "Backslash",
611 PhysicalKey::BracketLeft => "BracketLeft",
612 PhysicalKey::BracketRight => "BracketRight",
613 PhysicalKey::Comma => "Comma",
614 PhysicalKey::Digit0 => "Digit0",
615 PhysicalKey::Digit1 => "Digit1",
616 PhysicalKey::Digit2 => "Digit2",
617 PhysicalKey::Digit3 => "Digit3",
618 PhysicalKey::Digit4 => "Digit4",
619 PhysicalKey::Digit5 => "Digit5",
620 PhysicalKey::Digit6 => "Digit6",
621 PhysicalKey::Digit7 => "Digit7",
622 PhysicalKey::Digit8 => "Digit8",
623 PhysicalKey::Digit9 => "Digit9",
624 PhysicalKey::Equal => "Equal",
625 PhysicalKey::IntlBackslash => "IntlBackslash",
626 PhysicalKey::IntlRo => "IntlRo",
627 PhysicalKey::IntlYen => "IntlYen",
628 PhysicalKey::A => "A",
629 PhysicalKey::B => "B",
630 PhysicalKey::C => "C",
631 PhysicalKey::D => "D",
632 PhysicalKey::E => "E",
633 PhysicalKey::F => "F",
634 PhysicalKey::G => "G",
635 PhysicalKey::H => "H",
636 PhysicalKey::I => "I",
637 PhysicalKey::J => "J",
638 PhysicalKey::K => "K",
639 PhysicalKey::L => "L",
640 PhysicalKey::M => "M",
641 PhysicalKey::N => "N",
642 PhysicalKey::O => "O",
643 PhysicalKey::P => "P",
644 PhysicalKey::Q => "Q",
645 PhysicalKey::R => "R",
646 PhysicalKey::S => "S",
647 PhysicalKey::T => "T",
648 PhysicalKey::U => "U",
649 PhysicalKey::V => "V",
650 PhysicalKey::W => "W",
651 PhysicalKey::X => "X",
652 PhysicalKey::Y => "Y",
653 PhysicalKey::Z => "Z",
654 PhysicalKey::Minus => "Minus",
655 PhysicalKey::Period => "Period",
656 PhysicalKey::Quote => "Quote",
657 PhysicalKey::Semicolon => "Semicolon",
658 PhysicalKey::Slash => "Slash",
659 PhysicalKey::AltLeft => "AltLeft",
660 PhysicalKey::AltRight => "AltRight",
661 PhysicalKey::Backspace => "Backspace",
662 PhysicalKey::CapsLock => "CapsLock",
663 PhysicalKey::ContextMenu => "ContextMenu",
664 PhysicalKey::ControlLeft => "ControlLeft",
665 PhysicalKey::ControlRight => "ControlRight",
666 PhysicalKey::Enter => "Enter",
667 PhysicalKey::MetaLeft => "MetaLeft",
668 PhysicalKey::MetaRight => "MetaRight",
669 PhysicalKey::ShiftLeft => "ShiftLeft",
670 PhysicalKey::ShiftRight => "ShiftRight",
671 PhysicalKey::Space => "Space",
672 PhysicalKey::Tab => "Tab",
673 PhysicalKey::Convert => "Convert",
674 PhysicalKey::KanaMode => "KanaMode",
675 PhysicalKey::Lang1 => "Lang1",
676 PhysicalKey::Lang2 => "Lang2",
677 PhysicalKey::Lang3 => "Lang3",
678 PhysicalKey::Lang4 => "Lang4",
679 PhysicalKey::Lang5 => "Lang5",
680 PhysicalKey::NonConvert => "NonConvert",
681 PhysicalKey::Delete => "Delete",
682 PhysicalKey::End => "End",
683 PhysicalKey::Help => "Help",
684 PhysicalKey::Home => "Home",
685 PhysicalKey::Insert => "Insert",
686 PhysicalKey::PageDown => "PageDown",
687 PhysicalKey::PageUp => "PageUp",
688 PhysicalKey::ArrowDown => "ArrowDown",
689 PhysicalKey::ArrowLeft => "ArrowLeft",
690 PhysicalKey::ArrowRight => "ArrowRight",
691 PhysicalKey::ArrowUp => "ArrowUp",
692 PhysicalKey::NumLock => "NumLock",
693 PhysicalKey::NumPad0 => "NumPad0",
694 PhysicalKey::NumPad1 => "NumPad1",
695 PhysicalKey::NumPad2 => "NumPad2",
696 PhysicalKey::NumPad3 => "NumPad3",
697 PhysicalKey::NumPad4 => "NumPad4",
698 PhysicalKey::NumPad5 => "NumPad5",
699 PhysicalKey::NumPad6 => "NumPad6",
700 PhysicalKey::NumPad7 => "NumPad7",
701 PhysicalKey::NumPad8 => "NumPad8",
702 PhysicalKey::NumPad9 => "NumPad9",
703 PhysicalKey::NumPadAdd => "NumPadAdd",
704 PhysicalKey::NumPadClear => "NumPadClear",
705 PhysicalKey::NumPadComma => "NumPadComma",
706 PhysicalKey::NumPadDecimal => "NumPadDecimal",
707 PhysicalKey::NumPadDivide => "NumPadDivide",
708 PhysicalKey::NumPadEnter => "NumPadEnter",
709 PhysicalKey::NumPadEqual => "NumPadEqual",
710 PhysicalKey::NumPadMultiply => "NumPadMultiply",
711 PhysicalKey::NumPadParenLeft => "NumPadParenLeft",
712 PhysicalKey::NumPadParenRight => "NumPadParenRight",
713 PhysicalKey::NumPadSubtract => "NumPadSubtract",
714 PhysicalKey::Escape => "Escape",
715 PhysicalKey::F1 => "F1",
716 PhysicalKey::F2 => "F2",
717 PhysicalKey::F3 => "F3",
718 PhysicalKey::F4 => "F4",
719 PhysicalKey::F5 => "F5",
720 PhysicalKey::F6 => "F6",
721 PhysicalKey::F7 => "F7",
722 PhysicalKey::F8 => "F8",
723 PhysicalKey::F9 => "F9",
724 PhysicalKey::F10 => "F10",
725 PhysicalKey::F11 => "F11",
726 PhysicalKey::F12 => "F12",
727 PhysicalKey::F13 => "F13",
728 PhysicalKey::F14 => "F14",
729 PhysicalKey::F15 => "F15",
730 PhysicalKey::F16 => "F16",
731 PhysicalKey::F17 => "F17",
732 PhysicalKey::F18 => "F18",
733 PhysicalKey::F19 => "F19",
734 PhysicalKey::F20 => "F20",
735 PhysicalKey::F21 => "F21",
736 PhysicalKey::F22 => "F22",
737 PhysicalKey::F23 => "F23",
738 PhysicalKey::F24 => "F24",
739 PhysicalKey::PrintScreen => "PrintScreen",
740 PhysicalKey::ScrollLock => "ScrollLock",
741 PhysicalKey::Pause => "Pause",
742 PhysicalKey::BrowserBack => "BrowserBack",
743 PhysicalKey::BrowserFavorites => "BrowserFavorites",
744 PhysicalKey::BrowserForward => "BrowserForward",
745 PhysicalKey::BrowserHome => "BrowserHome",
746 PhysicalKey::BrowserRefresh => "BrowserRefresh",
747 PhysicalKey::BrowserSearch => "BrowserSearch",
748 PhysicalKey::BrowserStop => "BrowserStop",
749 PhysicalKey::Eject => "Eject",
750 PhysicalKey::LaunchApp1 => "LaunchApp1",
751 PhysicalKey::LaunchApp2 => "LaunchApp2",
752 PhysicalKey::LaunchMail => "LaunchMail",
753 PhysicalKey::MediaPlayPause => "MediaPlayPause",
754 PhysicalKey::MediaSelect => "MediaSelect",
755 PhysicalKey::MediaStop => "MediaStop",
756 PhysicalKey::MediaTrackNext => "MediaTrackNext",
757 PhysicalKey::MediaTrackPrevious => "MediaTrackPrevious",
758 PhysicalKey::Power => "Power",
759 PhysicalKey::Sleep => "Sleep",
760 PhysicalKey::AudioVolumeDown => "AudioVolumeDown",
761 PhysicalKey::AudioVolumeMute => "AudioVolumeMute",
762 PhysicalKey::AudioVolumeUp => "AudioVolumeUp",
763 PhysicalKey::WakeUp => "WakeUp",
764 PhysicalKey::Again => "Again",
765 PhysicalKey::Copy => "Copy",
766 PhysicalKey::Cut => "Cut",
767 PhysicalKey::Find => "Find",
768 PhysicalKey::Open => "Open",
769 PhysicalKey::Paste => "Paste",
770 PhysicalKey::Props => "Props",
771 PhysicalKey::Select => "Select",
772 PhysicalKey::Undo => "Undo",
773 }
774 }
775
776 pub fn parse(s: &str) -> Result<PhysicalKey, ParsePhysicalKeyError> {
779 let s = s.trim();
780 if let Some((_, value)) = NAMES.iter().find(|(name, _)| name.eq_ignore_ascii_case(s)) {
781 return Ok(*value);
782 }
783 if let Ok(number) = s.parse::<i32>() {
784 if let Some(value) = Self::from_value(number) {
785 return Ok(value);
786 }
787 }
788 Err(ParsePhysicalKeyError(s.to_string()))
789 }
790}
791
792impl FromStr for PhysicalKey {
793 type Err = ParsePhysicalKeyError;
794
795 fn from_str(s: &str) -> Result<Self, Self::Err> {
796 Self::parse(s)
797 }
798}
799
800impl fmt::Display for PhysicalKey {
801 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
802 f.write_str(self.name())
803 }
804}