1use crossterm::event::{self, KeyEvent, KeyEventState, KeyModifiers};
2use std::fmt;
3
4#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
6pub enum Key {
7 Enter,
9 Tab,
11 Backspace,
13 Esc,
15
16 Left,
18 Right,
20 Up,
22 Down,
24
25 Ins,
27 Delete,
29 Home,
31 End,
33 PageUp,
35 PageDown,
37
38 F0,
40 F1,
42 F2,
44 F3,
46 F4,
48 F5,
50 F6,
52 F7,
54 F8,
56 F9,
58 F10,
60 F11,
62 F12,
64 Char(char),
65 Ctrl(char),
66 Alt(char),
67 Unknown,
68}
69
70impl Key {
71 pub fn from_f(n: u8) -> Key {
79 match n {
80 0 => Key::F0,
81 1 => Key::F1,
82 2 => Key::F2,
83 3 => Key::F3,
84 4 => Key::F4,
85 5 => Key::F5,
86 6 => Key::F6,
87 7 => Key::F7,
88 8 => Key::F8,
89 9 => Key::F9,
90 10 => Key::F10,
91 11 => Key::F11,
92 12 => Key::F12,
93 _ => panic!("unknown function key: F{}", n),
94 }
95 }
96}
97
98impl fmt::Display for Key {
99 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
100 match *self {
101 Key::Alt(' ') => write!(f, "<Alt+Space>"),
102 Key::Ctrl(' ') => write!(f, "<Ctrl+Space>"),
103 Key::Char(' ') => write!(f, "<Space>"),
104 Key::Alt(c) => write!(f, "<Alt+{}>", c),
105 Key::Ctrl(c) => write!(f, "<Ctrl+{}>", c),
106 Key::Char(c) => write!(f, "{}", c),
107 Key::Left => write!(f, "←"),
108 Key::Right => write!(f, "→"),
109 Key::Up => write!(f, "↑"),
110 Key::Down => write!(f, "↓"),
111 Key::Enter
112 | Key::Tab
113 | Key::Backspace
114 | Key::Esc
115 | Key::Ins
116 | Key::Delete
117 | Key::Home
118 | Key::End
119 | Key::PageUp
120 | Key::PageDown => write!(f, "<{:?}>", self),
121 _ => write!(f, "{:?}", self),
122 }
123 }
124}
125
126impl From<Key> for KeyEvent {
127 fn from(value: Key) -> Self {
128 match value {
129 Key::Up => event::KeyEvent {
130 code: event::KeyCode::Up,
131 modifiers: KeyModifiers::empty(),
132 kind: event::KeyEventKind::Press,
133 state: KeyEventState::empty(),
134 },
135 Key::Down => event::KeyEvent {
136 code: event::KeyCode::Down,
137 modifiers: KeyModifiers::empty(),
138 kind: event::KeyEventKind::Press,
139 state: KeyEventState::empty(),
140 },
141 _ => unimplemented!(),
142 }
143 }
144}
145
146impl From<event::KeyEvent> for Key {
147 fn from(key_event: event::KeyEvent) -> Self {
148 match key_event {
149 event::KeyEvent {
150 code: event::KeyCode::Esc,
151 ..
152 } => Key::Esc,
153 event::KeyEvent {
154 code: event::KeyCode::Backspace,
155 ..
156 } => Key::Backspace,
157 event::KeyEvent {
158 code: event::KeyCode::Left,
159 ..
160 } => Key::Left,
161 event::KeyEvent {
162 code: event::KeyCode::Right,
163 ..
164 } => Key::Right,
165 event::KeyEvent {
166 code: event::KeyCode::Up,
167 ..
168 } => Key::Up,
169 event::KeyEvent {
170 code: event::KeyCode::Down,
171 ..
172 } => Key::Down,
173 event::KeyEvent {
174 code: event::KeyCode::Home,
175 ..
176 } => Key::Home,
177 event::KeyEvent {
178 code: event::KeyCode::End,
179 ..
180 } => Key::End,
181 event::KeyEvent {
182 code: event::KeyCode::PageUp,
183 ..
184 } => Key::PageUp,
185 event::KeyEvent {
186 code: event::KeyCode::PageDown,
187 ..
188 } => Key::PageDown,
189 event::KeyEvent {
190 code: event::KeyCode::Delete,
191 ..
192 } => Key::Delete,
193 event::KeyEvent {
194 code: event::KeyCode::Insert,
195 ..
196 } => Key::Ins,
197 event::KeyEvent {
198 code: event::KeyCode::F(n),
199 ..
200 } => Key::from_f(n),
201 event::KeyEvent {
202 code: event::KeyCode::Enter,
203 ..
204 } => Key::Enter,
205 event::KeyEvent {
206 code: event::KeyCode::Tab,
207 ..
208 } => Key::Tab,
209
210 event::KeyEvent {
212 code: event::KeyCode::Char(c),
213 modifiers: event::KeyModifiers::ALT,
214 ..
215 } => Key::Alt(c),
216 event::KeyEvent {
217 code: event::KeyCode::Char(c),
218 modifiers: event::KeyModifiers::CONTROL,
219 ..
220 } => Key::Ctrl(c),
221
222 event::KeyEvent {
223 code: event::KeyCode::Char(c),
224 ..
225 } => Key::Char(c),
226
227 _ => Key::Unknown,
228 }
229 }
230}