1use std::fmt;
5use std::str::FromStr;
6
7#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, PartialOrd, Ord)]
9#[repr(i32)]
10pub enum Key {
11 #[default]
13 None = 0,
14 Cancel = 1,
16 Back = 2,
18 Tab = 3,
20 LineFeed = 4,
22 Clear = 5,
24 Return = 6,
26 Pause = 7,
28 CapsLock = 8,
30 HangulMode = 9,
32 JunjaMode = 10,
34 FinalMode = 11,
36 KanjiMode = 12,
38 Escape = 13,
40 ImeConvert = 14,
42 ImeNonConvert = 15,
44 ImeAccept = 16,
46 ImeModeChange = 17,
48 Space = 18,
50 PageUp = 19,
52 PageDown = 20,
54 End = 21,
56 Home = 22,
58 Left = 23,
60 Up = 24,
62 Right = 25,
64 Down = 26,
66 Select = 27,
68 Print = 28,
70 Execute = 29,
72 Snapshot = 30,
74 Insert = 31,
76 Delete = 32,
78 Help = 33,
80 D0 = 34,
82 D1 = 35,
84 D2 = 36,
86 D3 = 37,
88 D4 = 38,
90 D5 = 39,
92 D6 = 40,
94 D7 = 41,
96 D8 = 42,
98 D9 = 43,
100 A = 44,
102 B = 45,
104 C = 46,
106 D = 47,
108 E = 48,
110 F = 49,
112 G = 50,
114 H = 51,
116 I = 52,
118 J = 53,
120 K = 54,
122 L = 55,
124 M = 56,
126 N = 57,
128 O = 58,
130 P = 59,
132 Q = 60,
134 R = 61,
136 S = 62,
138 T = 63,
140 U = 64,
142 V = 65,
144 W = 66,
146 X = 67,
148 Y = 68,
150 Z = 69,
152 LWin = 70,
154 RWin = 71,
156 Apps = 72,
158 Sleep = 73,
160 NumPad0 = 74,
162 NumPad1 = 75,
164 NumPad2 = 76,
166 NumPad3 = 77,
168 NumPad4 = 78,
170 NumPad5 = 79,
172 NumPad6 = 80,
174 NumPad7 = 81,
176 NumPad8 = 82,
178 NumPad9 = 83,
180 Multiply = 84,
182 Add = 85,
184 Separator = 86,
186 Subtract = 87,
188 Decimal = 88,
190 Divide = 89,
192 F1 = 90,
194 F2 = 91,
196 F3 = 92,
198 F4 = 93,
200 F5 = 94,
202 F6 = 95,
204 F7 = 96,
206 F8 = 97,
208 F9 = 98,
210 F10 = 99,
212 F11 = 100,
214 F12 = 101,
216 F13 = 102,
218 F14 = 103,
220 F15 = 104,
222 F16 = 105,
224 F17 = 106,
226 F18 = 107,
228 F19 = 108,
230 F20 = 109,
232 F21 = 110,
234 F22 = 111,
236 F23 = 112,
238 F24 = 113,
240 NumLock = 114,
242 Scroll = 115,
244 LeftShift = 116,
246 RightShift = 117,
248 LeftCtrl = 118,
250 RightCtrl = 119,
252 LeftAlt = 120,
254 RightAlt = 121,
256 BrowserBack = 122,
258 BrowserForward = 123,
260 BrowserRefresh = 124,
262 BrowserStop = 125,
264 BrowserSearch = 126,
266 BrowserFavorites = 127,
268 BrowserHome = 128,
270 VolumeMute = 129,
272 VolumeDown = 130,
274 VolumeUp = 131,
276 MediaNextTrack = 132,
278 MediaPreviousTrack = 133,
280 MediaStop = 134,
282 MediaPlayPause = 135,
284 LaunchMail = 136,
286 SelectMedia = 137,
288 LaunchApplication1 = 138,
290 LaunchApplication2 = 139,
292 OemSemicolon = 140,
294 OemPlus = 141,
296 OemComma = 142,
298 OemMinus = 143,
300 OemPeriod = 144,
302 OemQuestion = 145,
304 OemTilde = 146,
306 AbntC1 = 147,
308 AbntC2 = 148,
310 OemOpenBrackets = 149,
312 OemPipe = 150,
314 OemCloseBrackets = 151,
316 OemQuotes = 152,
318 Oem8 = 153,
320 OemBackslash = 154,
322 ImeProcessed = 155,
324 System = 156,
326 OemAttn = 157,
328 OemFinish = 158,
330 DbeHiragana = 159,
332 DbeSbcsChar = 160,
334 DbeDbcsChar = 161,
336 OemBackTab = 162,
338 DbeNoRoman = 163,
340 CrSel = 164,
342 ExSel = 165,
344 EraseEof = 166,
346 Play = 167,
348 DbeNoCodeInput = 168,
350 NoName = 169,
352 DbeEnterDialogConversionMode = 170,
354 OemClear = 171,
356 DeadCharProcessed = 172,
358 FnLeftArrow = 10001,
360 FnRightArrow = 10002,
362 FnUpArrow = 10003,
364 FnDownArrow = 10004,
366 MediaHome = 100000,
368 MediaChannelList = 100001,
370 MediaChannelRaise = 100002,
372 MediaChannelLower = 100003,
374 MediaRecord = 100005,
376 MediaRed = 100010,
378 MediaGreen = 100011,
380 MediaYellow = 100012,
382 MediaBlue = 100013,
384 MediaMenu = 100020,
386 MediaMore = 100021,
388 MediaOption = 100022,
390 MediaInfo = 100023,
392 MediaSearch = 100024,
394 MediaSubtitle = 100025,
396 MediaTvGuide = 100026,
398 MediaPreviousChannel = 100027,
400}
401
402#[derive(Clone, Debug, PartialEq, Eq)]
404pub struct ParseKeyError(pub String);
405
406impl fmt::Display for ParseKeyError {
407 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
408 write!(f, "Requested value '{}' was not found.", self.0)
409 }
410}
411
412impl std::error::Error for ParseKeyError {}
413
414static NAMES: &[(&str, Key)] = &[
416 ("None", Key::None),
417 ("Cancel", Key::Cancel),
418 ("Back", Key::Back),
419 ("Tab", Key::Tab),
420 ("LineFeed", Key::LineFeed),
421 ("Clear", Key::Clear),
422 ("Return", Key::Return),
423 ("Enter", Key::Return),
424 ("Pause", Key::Pause),
425 ("CapsLock", Key::CapsLock),
426 ("Capital", Key::CapsLock),
427 ("HangulMode", Key::HangulMode),
428 ("KanaMode", Key::HangulMode),
429 ("JunjaMode", Key::JunjaMode),
430 ("FinalMode", Key::FinalMode),
431 ("KanjiMode", Key::KanjiMode),
432 ("HanjaMode", Key::KanjiMode),
433 ("Escape", Key::Escape),
434 ("ImeConvert", Key::ImeConvert),
435 ("ImeNonConvert", Key::ImeNonConvert),
436 ("ImeAccept", Key::ImeAccept),
437 ("ImeModeChange", Key::ImeModeChange),
438 ("Space", Key::Space),
439 ("PageUp", Key::PageUp),
440 ("Prior", Key::PageUp),
441 ("PageDown", Key::PageDown),
442 ("Next", Key::PageDown),
443 ("End", Key::End),
444 ("Home", Key::Home),
445 ("Left", Key::Left),
446 ("Up", Key::Up),
447 ("Right", Key::Right),
448 ("Down", Key::Down),
449 ("Select", Key::Select),
450 ("Print", Key::Print),
451 ("Execute", Key::Execute),
452 ("Snapshot", Key::Snapshot),
453 ("PrintScreen", Key::Snapshot),
454 ("Insert", Key::Insert),
455 ("Delete", Key::Delete),
456 ("Help", Key::Help),
457 ("D0", Key::D0),
458 ("D1", Key::D1),
459 ("D2", Key::D2),
460 ("D3", Key::D3),
461 ("D4", Key::D4),
462 ("D5", Key::D5),
463 ("D6", Key::D6),
464 ("D7", Key::D7),
465 ("D8", Key::D8),
466 ("D9", Key::D9),
467 ("A", Key::A),
468 ("B", Key::B),
469 ("C", Key::C),
470 ("D", Key::D),
471 ("E", Key::E),
472 ("F", Key::F),
473 ("G", Key::G),
474 ("H", Key::H),
475 ("I", Key::I),
476 ("J", Key::J),
477 ("K", Key::K),
478 ("L", Key::L),
479 ("M", Key::M),
480 ("N", Key::N),
481 ("O", Key::O),
482 ("P", Key::P),
483 ("Q", Key::Q),
484 ("R", Key::R),
485 ("S", Key::S),
486 ("T", Key::T),
487 ("U", Key::U),
488 ("V", Key::V),
489 ("W", Key::W),
490 ("X", Key::X),
491 ("Y", Key::Y),
492 ("Z", Key::Z),
493 ("LWin", Key::LWin),
494 ("RWin", Key::RWin),
495 ("Apps", Key::Apps),
496 ("Sleep", Key::Sleep),
497 ("NumPad0", Key::NumPad0),
498 ("NumPad1", Key::NumPad1),
499 ("NumPad2", Key::NumPad2),
500 ("NumPad3", Key::NumPad3),
501 ("NumPad4", Key::NumPad4),
502 ("NumPad5", Key::NumPad5),
503 ("NumPad6", Key::NumPad6),
504 ("NumPad7", Key::NumPad7),
505 ("NumPad8", Key::NumPad8),
506 ("NumPad9", Key::NumPad9),
507 ("Multiply", Key::Multiply),
508 ("Add", Key::Add),
509 ("Separator", Key::Separator),
510 ("Subtract", Key::Subtract),
511 ("Decimal", Key::Decimal),
512 ("Divide", Key::Divide),
513 ("F1", Key::F1),
514 ("F2", Key::F2),
515 ("F3", Key::F3),
516 ("F4", Key::F4),
517 ("F5", Key::F5),
518 ("F6", Key::F6),
519 ("F7", Key::F7),
520 ("F8", Key::F8),
521 ("F9", Key::F9),
522 ("F10", Key::F10),
523 ("F11", Key::F11),
524 ("F12", Key::F12),
525 ("F13", Key::F13),
526 ("F14", Key::F14),
527 ("F15", Key::F15),
528 ("F16", Key::F16),
529 ("F17", Key::F17),
530 ("F18", Key::F18),
531 ("F19", Key::F19),
532 ("F20", Key::F20),
533 ("F21", Key::F21),
534 ("F22", Key::F22),
535 ("F23", Key::F23),
536 ("F24", Key::F24),
537 ("NumLock", Key::NumLock),
538 ("Scroll", Key::Scroll),
539 ("LeftShift", Key::LeftShift),
540 ("RightShift", Key::RightShift),
541 ("LeftCtrl", Key::LeftCtrl),
542 ("RightCtrl", Key::RightCtrl),
543 ("LeftAlt", Key::LeftAlt),
544 ("RightAlt", Key::RightAlt),
545 ("BrowserBack", Key::BrowserBack),
546 ("BrowserForward", Key::BrowserForward),
547 ("BrowserRefresh", Key::BrowserRefresh),
548 ("BrowserStop", Key::BrowserStop),
549 ("BrowserSearch", Key::BrowserSearch),
550 ("BrowserFavorites", Key::BrowserFavorites),
551 ("BrowserHome", Key::BrowserHome),
552 ("VolumeMute", Key::VolumeMute),
553 ("VolumeDown", Key::VolumeDown),
554 ("VolumeUp", Key::VolumeUp),
555 ("MediaNextTrack", Key::MediaNextTrack),
556 ("MediaPreviousTrack", Key::MediaPreviousTrack),
557 ("MediaStop", Key::MediaStop),
558 ("MediaPlayPause", Key::MediaPlayPause),
559 ("LaunchMail", Key::LaunchMail),
560 ("SelectMedia", Key::SelectMedia),
561 ("LaunchApplication1", Key::LaunchApplication1),
562 ("LaunchApplication2", Key::LaunchApplication2),
563 ("OemSemicolon", Key::OemSemicolon),
564 ("Oem1", Key::OemSemicolon),
565 ("OemPlus", Key::OemPlus),
566 ("OemComma", Key::OemComma),
567 ("OemMinus", Key::OemMinus),
568 ("OemPeriod", Key::OemPeriod),
569 ("OemQuestion", Key::OemQuestion),
570 ("Oem2", Key::OemQuestion),
571 ("OemTilde", Key::OemTilde),
572 ("Oem3", Key::OemTilde),
573 ("AbntC1", Key::AbntC1),
574 ("AbntC2", Key::AbntC2),
575 ("OemOpenBrackets", Key::OemOpenBrackets),
576 ("Oem4", Key::OemOpenBrackets),
577 ("OemPipe", Key::OemPipe),
578 ("Oem5", Key::OemPipe),
579 ("OemCloseBrackets", Key::OemCloseBrackets),
580 ("Oem6", Key::OemCloseBrackets),
581 ("OemQuotes", Key::OemQuotes),
582 ("Oem7", Key::OemQuotes),
583 ("Oem8", Key::Oem8),
584 ("OemBackslash", Key::OemBackslash),
585 ("Oem102", Key::OemBackslash),
586 ("ImeProcessed", Key::ImeProcessed),
587 ("System", Key::System),
588 ("OemAttn", Key::OemAttn),
589 ("DbeAlphanumeric", Key::OemAttn),
590 ("OemFinish", Key::OemFinish),
591 ("DbeKatakana", Key::OemFinish),
592 ("DbeHiragana", Key::DbeHiragana),
593 ("OemCopy", Key::DbeHiragana),
594 ("DbeSbcsChar", Key::DbeSbcsChar),
595 ("OemAuto", Key::DbeSbcsChar),
596 ("DbeDbcsChar", Key::DbeDbcsChar),
597 ("OemEnlw", Key::DbeDbcsChar),
598 ("OemBackTab", Key::OemBackTab),
599 ("DbeRoman", Key::OemBackTab),
600 ("DbeNoRoman", Key::DbeNoRoman),
601 ("Attn", Key::DbeNoRoman),
602 ("CrSel", Key::CrSel),
603 ("DbeEnterWordRegisterMode", Key::CrSel),
604 ("ExSel", Key::ExSel),
605 ("DbeEnterImeConfigureMode", Key::ExSel),
606 ("EraseEof", Key::EraseEof),
607 ("DbeFlushString", Key::EraseEof),
608 ("Play", Key::Play),
609 ("DbeCodeInput", Key::Play),
610 ("DbeNoCodeInput", Key::DbeNoCodeInput),
611 ("Zoom", Key::DbeNoCodeInput),
612 ("NoName", Key::NoName),
613 ("DbeDetermineString", Key::NoName),
614 ("DbeEnterDialogConversionMode", Key::DbeEnterDialogConversionMode),
615 ("Pa1", Key::DbeEnterDialogConversionMode),
616 ("OemClear", Key::OemClear),
617 ("DeadCharProcessed", Key::DeadCharProcessed),
618 ("FnLeftArrow", Key::FnLeftArrow),
619 ("FnRightArrow", Key::FnRightArrow),
620 ("FnUpArrow", Key::FnUpArrow),
621 ("FnDownArrow", Key::FnDownArrow),
622 ("MediaHome", Key::MediaHome),
623 ("MediaChannelList", Key::MediaChannelList),
624 ("MediaChannelRaise", Key::MediaChannelRaise),
625 ("MediaChannelLower", Key::MediaChannelLower),
626 ("MediaRecord", Key::MediaRecord),
627 ("MediaRed", Key::MediaRed),
628 ("MediaGreen", Key::MediaGreen),
629 ("MediaYellow", Key::MediaYellow),
630 ("MediaBlue", Key::MediaBlue),
631 ("MediaMenu", Key::MediaMenu),
632 ("MediaMore", Key::MediaMore),
633 ("MediaOption", Key::MediaOption),
634 ("MediaInfo", Key::MediaInfo),
635 ("MediaSearch", Key::MediaSearch),
636 ("MediaSubtitle", Key::MediaSubtitle),
637 ("MediaTvGuide", Key::MediaTvGuide),
638 ("MediaPreviousChannel", Key::MediaPreviousChannel),
639];
640
641#[allow(non_upper_case_globals)]
642impl Key {
643 pub const Enter: Key = Key::Return;
645
646 pub const Capital: Key = Key::CapsLock;
648
649 pub const KanaMode: Key = Key::HangulMode;
651
652 pub const HanjaMode: Key = Key::KanjiMode;
654
655 pub const Prior: Key = Key::PageUp;
657
658 pub const Next: Key = Key::PageDown;
660
661 pub const PrintScreen: Key = Key::Snapshot;
663
664 pub const Oem1: Key = Key::OemSemicolon;
666
667 pub const Oem2: Key = Key::OemQuestion;
669
670 pub const Oem3: Key = Key::OemTilde;
672
673 pub const Oem4: Key = Key::OemOpenBrackets;
675
676 pub const Oem5: Key = Key::OemPipe;
678
679 pub const Oem6: Key = Key::OemCloseBrackets;
681
682 pub const Oem7: Key = Key::OemQuotes;
684
685 pub const Oem102: Key = Key::OemBackslash;
687
688 pub const DbeAlphanumeric: Key = Key::OemAttn;
690
691 pub const DbeKatakana: Key = Key::OemFinish;
693
694 pub const OemCopy: Key = Key::DbeHiragana;
696
697 pub const OemAuto: Key = Key::DbeSbcsChar;
699
700 pub const OemEnlw: Key = Key::DbeDbcsChar;
702
703 pub const DbeRoman: Key = Key::OemBackTab;
705
706 pub const Attn: Key = Key::DbeNoRoman;
708
709 pub const DbeEnterWordRegisterMode: Key = Key::CrSel;
711
712 pub const DbeEnterImeConfigureMode: Key = Key::ExSel;
714
715 pub const DbeFlushString: Key = Key::EraseEof;
717
718 pub const DbeCodeInput: Key = Key::Play;
720
721 pub const Zoom: Key = Key::DbeNoCodeInput;
723
724 pub const DbeDetermineString: Key = Key::NoName;
726
727 pub const Pa1: Key = Key::DbeEnterDialogConversionMode;
729
730 #[inline]
732 pub const fn value(self) -> i32 {
733 self as i32
734 }
735
736 pub fn from_value(value: i32) -> Option<Key> {
738 NAMES.iter().map(|(_, k)| *k).find(|k| *k as i32 == value)
739 }
740
741 pub fn name(self) -> &'static str {
744 match self {
745 Key::None => "None",
746 Key::Cancel => "Cancel",
747 Key::Back => "Back",
748 Key::Tab => "Tab",
749 Key::LineFeed => "LineFeed",
750 Key::Clear => "Clear",
751 Key::Return => "Return",
752 Key::Pause => "Pause",
753 Key::CapsLock => "CapsLock",
754 Key::HangulMode => "HangulMode",
755 Key::JunjaMode => "JunjaMode",
756 Key::FinalMode => "FinalMode",
757 Key::KanjiMode => "KanjiMode",
758 Key::Escape => "Escape",
759 Key::ImeConvert => "ImeConvert",
760 Key::ImeNonConvert => "ImeNonConvert",
761 Key::ImeAccept => "ImeAccept",
762 Key::ImeModeChange => "ImeModeChange",
763 Key::Space => "Space",
764 Key::PageUp => "PageUp",
765 Key::PageDown => "PageDown",
766 Key::End => "End",
767 Key::Home => "Home",
768 Key::Left => "Left",
769 Key::Up => "Up",
770 Key::Right => "Right",
771 Key::Down => "Down",
772 Key::Select => "Select",
773 Key::Print => "Print",
774 Key::Execute => "Execute",
775 Key::Snapshot => "Snapshot",
776 Key::Insert => "Insert",
777 Key::Delete => "Delete",
778 Key::Help => "Help",
779 Key::D0 => "D0",
780 Key::D1 => "D1",
781 Key::D2 => "D2",
782 Key::D3 => "D3",
783 Key::D4 => "D4",
784 Key::D5 => "D5",
785 Key::D6 => "D6",
786 Key::D7 => "D7",
787 Key::D8 => "D8",
788 Key::D9 => "D9",
789 Key::A => "A",
790 Key::B => "B",
791 Key::C => "C",
792 Key::D => "D",
793 Key::E => "E",
794 Key::F => "F",
795 Key::G => "G",
796 Key::H => "H",
797 Key::I => "I",
798 Key::J => "J",
799 Key::K => "K",
800 Key::L => "L",
801 Key::M => "M",
802 Key::N => "N",
803 Key::O => "O",
804 Key::P => "P",
805 Key::Q => "Q",
806 Key::R => "R",
807 Key::S => "S",
808 Key::T => "T",
809 Key::U => "U",
810 Key::V => "V",
811 Key::W => "W",
812 Key::X => "X",
813 Key::Y => "Y",
814 Key::Z => "Z",
815 Key::LWin => "LWin",
816 Key::RWin => "RWin",
817 Key::Apps => "Apps",
818 Key::Sleep => "Sleep",
819 Key::NumPad0 => "NumPad0",
820 Key::NumPad1 => "NumPad1",
821 Key::NumPad2 => "NumPad2",
822 Key::NumPad3 => "NumPad3",
823 Key::NumPad4 => "NumPad4",
824 Key::NumPad5 => "NumPad5",
825 Key::NumPad6 => "NumPad6",
826 Key::NumPad7 => "NumPad7",
827 Key::NumPad8 => "NumPad8",
828 Key::NumPad9 => "NumPad9",
829 Key::Multiply => "Multiply",
830 Key::Add => "Add",
831 Key::Separator => "Separator",
832 Key::Subtract => "Subtract",
833 Key::Decimal => "Decimal",
834 Key::Divide => "Divide",
835 Key::F1 => "F1",
836 Key::F2 => "F2",
837 Key::F3 => "F3",
838 Key::F4 => "F4",
839 Key::F5 => "F5",
840 Key::F6 => "F6",
841 Key::F7 => "F7",
842 Key::F8 => "F8",
843 Key::F9 => "F9",
844 Key::F10 => "F10",
845 Key::F11 => "F11",
846 Key::F12 => "F12",
847 Key::F13 => "F13",
848 Key::F14 => "F14",
849 Key::F15 => "F15",
850 Key::F16 => "F16",
851 Key::F17 => "F17",
852 Key::F18 => "F18",
853 Key::F19 => "F19",
854 Key::F20 => "F20",
855 Key::F21 => "F21",
856 Key::F22 => "F22",
857 Key::F23 => "F23",
858 Key::F24 => "F24",
859 Key::NumLock => "NumLock",
860 Key::Scroll => "Scroll",
861 Key::LeftShift => "LeftShift",
862 Key::RightShift => "RightShift",
863 Key::LeftCtrl => "LeftCtrl",
864 Key::RightCtrl => "RightCtrl",
865 Key::LeftAlt => "LeftAlt",
866 Key::RightAlt => "RightAlt",
867 Key::BrowserBack => "BrowserBack",
868 Key::BrowserForward => "BrowserForward",
869 Key::BrowserRefresh => "BrowserRefresh",
870 Key::BrowserStop => "BrowserStop",
871 Key::BrowserSearch => "BrowserSearch",
872 Key::BrowserFavorites => "BrowserFavorites",
873 Key::BrowserHome => "BrowserHome",
874 Key::VolumeMute => "VolumeMute",
875 Key::VolumeDown => "VolumeDown",
876 Key::VolumeUp => "VolumeUp",
877 Key::MediaNextTrack => "MediaNextTrack",
878 Key::MediaPreviousTrack => "MediaPreviousTrack",
879 Key::MediaStop => "MediaStop",
880 Key::MediaPlayPause => "MediaPlayPause",
881 Key::LaunchMail => "LaunchMail",
882 Key::SelectMedia => "SelectMedia",
883 Key::LaunchApplication1 => "LaunchApplication1",
884 Key::LaunchApplication2 => "LaunchApplication2",
885 Key::OemSemicolon => "OemSemicolon",
886 Key::OemPlus => "OemPlus",
887 Key::OemComma => "OemComma",
888 Key::OemMinus => "OemMinus",
889 Key::OemPeriod => "OemPeriod",
890 Key::OemQuestion => "OemQuestion",
891 Key::OemTilde => "OemTilde",
892 Key::AbntC1 => "AbntC1",
893 Key::AbntC2 => "AbntC2",
894 Key::OemOpenBrackets => "OemOpenBrackets",
895 Key::OemPipe => "OemPipe",
896 Key::OemCloseBrackets => "OemCloseBrackets",
897 Key::OemQuotes => "OemQuotes",
898 Key::Oem8 => "Oem8",
899 Key::OemBackslash => "OemBackslash",
900 Key::ImeProcessed => "ImeProcessed",
901 Key::System => "System",
902 Key::OemAttn => "OemAttn",
903 Key::OemFinish => "OemFinish",
904 Key::DbeHiragana => "DbeHiragana",
905 Key::DbeSbcsChar => "DbeSbcsChar",
906 Key::DbeDbcsChar => "DbeDbcsChar",
907 Key::OemBackTab => "OemBackTab",
908 Key::DbeNoRoman => "DbeNoRoman",
909 Key::CrSel => "CrSel",
910 Key::ExSel => "ExSel",
911 Key::EraseEof => "EraseEof",
912 Key::Play => "Play",
913 Key::DbeNoCodeInput => "DbeNoCodeInput",
914 Key::NoName => "NoName",
915 Key::DbeEnterDialogConversionMode => "DbeEnterDialogConversionMode",
916 Key::OemClear => "OemClear",
917 Key::DeadCharProcessed => "DeadCharProcessed",
918 Key::FnLeftArrow => "FnLeftArrow",
919 Key::FnRightArrow => "FnRightArrow",
920 Key::FnUpArrow => "FnUpArrow",
921 Key::FnDownArrow => "FnDownArrow",
922 Key::MediaHome => "MediaHome",
923 Key::MediaChannelList => "MediaChannelList",
924 Key::MediaChannelRaise => "MediaChannelRaise",
925 Key::MediaChannelLower => "MediaChannelLower",
926 Key::MediaRecord => "MediaRecord",
927 Key::MediaRed => "MediaRed",
928 Key::MediaGreen => "MediaGreen",
929 Key::MediaYellow => "MediaYellow",
930 Key::MediaBlue => "MediaBlue",
931 Key::MediaMenu => "MediaMenu",
932 Key::MediaMore => "MediaMore",
933 Key::MediaOption => "MediaOption",
934 Key::MediaInfo => "MediaInfo",
935 Key::MediaSearch => "MediaSearch",
936 Key::MediaSubtitle => "MediaSubtitle",
937 Key::MediaTvGuide => "MediaTvGuide",
938 Key::MediaPreviousChannel => "MediaPreviousChannel",
939 }
940 }
941
942 pub fn parse(s: &str) -> Result<Key, ParseKeyError> {
945 let s = s.trim();
946 if let Some((_, value)) = NAMES.iter().find(|(name, _)| name.eq_ignore_ascii_case(s)) {
947 return Ok(*value);
948 }
949 if let Ok(number) = s.parse::<i32>() {
950 if let Some(value) = Self::from_value(number) {
951 return Ok(value);
952 }
953 }
954 Err(ParseKeyError(s.to_string()))
955 }
956}
957
958impl FromStr for Key {
959 type Err = ParseKeyError;
960
961 fn from_str(s: &str) -> Result<Self, Self::Err> {
962 Self::parse(s)
963 }
964}
965
966impl fmt::Display for Key {
967 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
968 f.write_str(self.name())
969 }
970}
971
972#[cfg(test)]
973mod tests {
974 use super::*;
975
976 #[test]
977 fn aliases_share_values() {
978 assert_eq!(Key::Enter, Key::Return);
979 assert_eq!(Key::Enter.value(), 6);
980 assert_eq!(Key::parse("enter"), Ok(Key::Return));
981 assert_eq!(Key::parse("ENTER"), Ok(Key::Enter));
982 }
983
984 #[test]
985 fn parse_and_display_round_trip() {
986 for (name, key) in NAMES {
987 assert_eq!(Key::parse(name), Ok(*key));
988 assert_eq!(Key::parse(key.name()), Ok(*key));
989 }
990 assert_eq!(Key::A.to_string(), "A");
991 assert_eq!(Key::None.to_string(), "None");
992 assert_eq!(Key::parse("44"), Ok(Key::A));
993 assert!(Key::parse("NotAKey").is_err());
994 }
995}