1#[derive(Clone, Copy, PartialEq, Eq, Debug)]
16pub enum KeyCode {
17 Esc,
18 Enter,
19 Backspace,
20 Delete,
21 Left,
22 Right,
23 Up,
24 Down,
25 Home,
26 End,
27 Tab,
28 BackTab,
29 Char(char),
30}
31
32#[derive(Clone, Copy, PartialEq, Eq, Debug, Default)]
35pub struct KeyModifiers {
36 pub ctrl: bool,
37 pub alt: bool,
38 pub shift: bool,
39}
40
41impl KeyModifiers {
42 pub const NONE: Self = Self {
43 ctrl: false,
44 alt: false,
45 shift: false,
46 };
47 pub const CONTROL: Self = Self {
48 ctrl: true,
49 alt: false,
50 shift: false,
51 };
52 pub const ALT: Self = Self {
53 ctrl: false,
54 alt: true,
55 shift: false,
56 };
57 pub const SHIFT: Self = Self {
58 ctrl: false,
59 alt: false,
60 shift: true,
61 };
62
63 pub fn contains(self, other: Self) -> bool {
64 (!other.ctrl || self.ctrl) && (!other.alt || self.alt) && (!other.shift || self.shift)
65 }
66}
67
68#[derive(Clone, Copy, PartialEq, Eq, Debug)]
70pub struct KeyEvent {
71 pub code: KeyCode,
72 pub modifiers: KeyModifiers,
73}
74
75impl KeyEvent {
76 pub fn new(code: KeyCode, modifiers: KeyModifiers) -> Self {
77 Self { code, modifiers }
78 }
79
80 pub fn bare(code: KeyCode) -> Self {
82 Self {
83 code,
84 modifiers: KeyModifiers::NONE,
85 }
86 }
87
88 pub fn ctrl(code: KeyCode) -> Self {
89 Self {
90 code,
91 modifiers: KeyModifiers::CONTROL,
92 }
93 }
94}
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99
100 #[test]
101 fn none_contains_nothing_and_is_contained_by_everything() {
102 assert!(KeyModifiers::NONE.contains(KeyModifiers::NONE));
103 assert!(!KeyModifiers::NONE.contains(KeyModifiers::CONTROL));
104 assert!(KeyModifiers::CONTROL.contains(KeyModifiers::NONE));
105 }
106
107 #[test]
108 fn contains_asks_for_a_subset_not_equality() {
109 let ctrl_shift = KeyModifiers {
110 ctrl: true,
111 alt: false,
112 shift: true,
113 };
114 assert!(ctrl_shift.contains(KeyModifiers::CONTROL));
115 assert!(ctrl_shift.contains(KeyModifiers::SHIFT));
116 assert!(!ctrl_shift.contains(KeyModifiers::ALT));
117 }
118
119 #[test]
120 fn constructors_agree_with_literals() {
121 assert_eq!(
122 KeyEvent::bare(KeyCode::Enter),
123 KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE)
124 );
125 assert_eq!(
126 KeyEvent::ctrl(KeyCode::Char('w')),
127 KeyEvent::new(KeyCode::Char('w'), KeyModifiers::CONTROL)
128 );
129 }
130}