1use std::fmt;
2
3#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Hash)]
5pub struct KeyEvent {
6 pub code: KeyCode,
8 pub modifiers: KeyModifiers,
10}
11
12impl fmt::Display for KeyEvent {
13 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
14 let code = format!("{}", self.code);
15 let modifiers = self.modifiers.iter().map(|m| match m {
16 KeyModifier::Shift => "",
17 KeyModifier::Control => "Ctrl-",
18 KeyModifier::Alt => "Alt-",
19 KeyModifier::Super => "Su-",
20 KeyModifier::Hyper => "H-",
21 KeyModifier::Meta => "M-",
22 });
23 let mods = modifiers.collect::<String>();
24
25 write!(f, "{mods}{code}",)
26 }
27}
28
29impl KeyEvent {
30 #[must_use]
32 pub fn new(code: KeyCode) -> Self {
33 Self {
34 code,
35 modifiers: KeyModifiers::new(),
36 }
37 }
38 #[must_use]
40 pub fn shift(code: KeyCode) -> Self {
41 Self {
42 modifiers: KeyModifiers::shift(),
43 code,
44 }
45 }
46
47 #[must_use]
49 pub fn ctrl(code: KeyCode) -> Self {
50 Self {
51 modifiers: KeyModifiers::ctrl(),
52 code,
53 }
54 }
55
56 #[must_use]
58 pub fn alt(code: KeyCode) -> Self {
59 Self {
60 modifiers: KeyModifiers::alt(),
61 code,
62 }
63 }
64
65 #[must_use]
67 pub fn modifier(mut self, modifier: KeyModifier) -> Self {
68 self.modifiers = self.modifiers.add_modifier(modifier);
69 self
70 }
71}
72
73#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
74pub enum KeyModifier {
75 Shift,
76 Control,
77 Alt,
78 Super,
79 Hyper,
80 Meta,
81}
82
83impl fmt::Display for KeyModifier {
84 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
85 match self {
86 KeyModifier::Shift => write!(f, "Shift"),
87 KeyModifier::Control => write!(f, "Ctrl"),
88 KeyModifier::Alt => write!(f, "Alt"),
89 KeyModifier::Super => write!(f, "Super"),
90 KeyModifier::Hyper => write!(f, "Hyper"),
91 KeyModifier::Meta => write!(f, "Meta"),
92 }
93 }
94}
95
96#[derive(Debug, Copy, Clone, PartialOrd, PartialEq, Eq, Hash, Default)]
97pub struct KeyModifiers(u32);
98
99impl KeyModifiers {
100 #[must_use]
102 pub fn new() -> Self {
103 KeyModifiers(0)
104 }
105
106 #[must_use]
108 pub fn shift() -> Self {
109 KeyModifiers(0).add_modifier(KeyModifier::Shift)
110 }
111
112 #[must_use]
114 pub fn ctrl() -> Self {
115 KeyModifiers(0).add_modifier(KeyModifier::Control)
116 }
117
118 #[must_use]
120 pub fn alt() -> Self {
121 KeyModifiers(0).add_modifier(KeyModifier::Alt)
122 }
123
124 #[must_use]
125 pub fn add_modifier(mut self, modifier: KeyModifier) -> Self {
126 match modifier {
127 KeyModifier::Shift => self.0 |= 0b0000_0001,
128 KeyModifier::Control => self.0 |= 0b0000_0010,
129 KeyModifier::Alt => self.0 |= 0b0000_0100,
130 KeyModifier::Super => self.0 |= 0b0000_1000,
131 KeyModifier::Hyper => self.0 |= 0b0001_0000,
132 KeyModifier::Meta => self.0 |= 0b0010_0000,
133 }
134 self
135 }
136
137 #[must_use]
138 pub fn remove_modifier(mut self, modifier: KeyModifier) -> Self {
139 match modifier {
140 KeyModifier::Shift => self.0 &= !0b0000_0001,
141 KeyModifier::Control => self.0 &= !0b0000_0010,
142 KeyModifier::Alt => self.0 &= !0b0000_0100,
143 KeyModifier::Super => self.0 &= !0b0000_1000,
144 KeyModifier::Hyper => self.0 &= !0b0001_0000,
145 KeyModifier::Meta => self.0 &= !0b0010_0000,
146 }
147 self
148 }
149
150 #[must_use]
151 pub fn contains(&self, modifier: KeyModifier) -> bool {
152 match modifier {
153 KeyModifier::Shift => self.0 & 0b0000_0001 != 0,
154 KeyModifier::Control => self.0 & 0b0000_0010 != 0,
155 KeyModifier::Alt => self.0 & 0b0000_0100 != 0,
156 KeyModifier::Super => self.0 & 0b0000_1000 != 0,
157 KeyModifier::Hyper => self.0 & 0b0001_0000 != 0,
158 KeyModifier::Meta => self.0 & 0b0010_0000 != 0,
159 }
160 }
161
162 pub fn iter(&self) -> impl Iterator<Item = KeyModifier> + '_ {
163 [
164 KeyModifier::Shift,
165 KeyModifier::Control,
166 KeyModifier::Alt,
167 KeyModifier::Super,
168 KeyModifier::Hyper,
169 KeyModifier::Meta,
170 ]
171 .into_iter()
172 .filter(|&m| self.contains(m))
173 }
174}
175
176#[derive(Debug, PartialOrd, PartialEq, Eq, Clone, Copy, Hash)]
178pub enum KeyCode {
179 Backspace,
180 Enter,
181 Left,
182 Right,
183 Up,
184 Down,
185 Home,
186 End,
187 PageUp,
188 PageDown,
189 Tab,
190 BackTab,
191 Delete,
192 Insert,
193 F(u8),
194 Char(char),
195 Null,
196 Esc,
197 Unknown,
198}
199
200impl fmt::Display for KeyCode {
201 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
202 match self {
203 KeyCode::Backspace => write!(f, "Backspace"),
204 KeyCode::Enter => write!(f, "Enter"),
205 KeyCode::Left => write!(f, "←"),
206 KeyCode::Right => write!(f, "→"),
207 KeyCode::Up => write!(f, "↑"),
208 KeyCode::Down => write!(f, "↓"),
209 KeyCode::Home => write!(f, "Home"),
210 KeyCode::End => write!(f, "End"),
211 KeyCode::PageUp => write!(f, "PageUp"),
212 KeyCode::PageDown => write!(f, "PageDown"),
213 KeyCode::Tab => write!(f, "Tab"),
214 KeyCode::BackTab => write!(f, "BackTab"),
215 KeyCode::Delete => write!(f, "Delete"),
216 KeyCode::Insert => write!(f, "Insert"),
217 KeyCode::F(n) => write!(f, "F{n}"),
218 KeyCode::Char(c) => write!(f, "{c}"),
219 KeyCode::Null => write!(f, "Null"),
220 KeyCode::Esc => write!(f, "Esc"),
221 KeyCode::Unknown => write!(f, "Unknown"),
222 }
223 }
224}