1use std::fmt::{self, Display, Formatter};
2
3use crossterm::event;
4
5#[derive(PartialEq, Eq, Clone, Copy, Debug, Hash)]
6pub enum Key {
7 Enter,
9 Tab,
10 Backspace,
11 Esc,
12 Left,
14 Right,
16 Up,
18 Down,
20 Ins,
21 Delete,
22 Home,
23 End,
24 PageUp,
25 PageDown,
26 F0,
27 F1,
28 F2,
29 F3,
30 F4,
31 F5,
32 F6,
33 F7,
34 F8,
35 F9,
36 F10,
37 F11,
38 F12,
39 Char(char),
40 Ctrl(char),
41 Alt(char),
42 Shift(char),
43 Unknown,
44}
45
46impl Key {
47 pub fn from_f(n: u8) -> Key {
51 match n {
52 0 => Key::F0,
53 1 => Key::F1,
54 2 => Key::F2,
55 3 => Key::F3,
56 4 => Key::F4,
57 5 => Key::F5,
58 6 => Key::F6,
59 7 => Key::F7,
60 8 => Key::F8,
61 9 => Key::F9,
62 10 => Key::F10,
63 11 => Key::F11,
64 12 => Key::F12,
65 _ => {
66 log::warn!("unknown function key: F{}", n);
67 Key::Unknown
68 }
69 }
70 }
71}
72
73impl From<event::KeyEvent> for Key {
74 fn from(key_event: event::KeyEvent) -> Self {
75 match key_event {
76 event::KeyEvent {
77 code: event::KeyCode::Esc,
78 ..
79 } => Key::Esc,
80 event::KeyEvent {
81 code: event::KeyCode::Backspace,
82 ..
83 } => Key::Backspace,
84 event::KeyEvent {
85 code: event::KeyCode::Left,
86 ..
87 } => Key::Left,
88 event::KeyEvent {
89 code: event::KeyCode::Right,
90 ..
91 } => Key::Right,
92 event::KeyEvent {
93 code: event::KeyCode::Up,
94 ..
95 } => Key::Up,
96 event::KeyEvent {
97 code: event::KeyCode::Down,
98 ..
99 } => Key::Down,
100 event::KeyEvent {
101 code: event::KeyCode::Home,
102 ..
103 } => Key::Home,
104 event::KeyEvent {
105 code: event::KeyCode::End,
106 ..
107 } => Key::End,
108 event::KeyEvent {
109 code: event::KeyCode::PageUp,
110 ..
111 } => Key::PageUp,
112 event::KeyEvent {
113 code: event::KeyCode::PageDown,
114 ..
115 } => Key::PageDown,
116 event::KeyEvent {
117 code: event::KeyCode::Delete,
118 ..
119 } => Key::Delete,
120 event::KeyEvent {
121 code: event::KeyCode::Insert,
122 ..
123 } => Key::Ins,
124 event::KeyEvent {
125 code: event::KeyCode::F(n),
126 ..
127 } => Key::from_f(n),
128 event::KeyEvent {
129 code: event::KeyCode::Enter,
130 ..
131 } => Key::Enter,
132 event::KeyEvent {
133 code: event::KeyCode::Tab,
134 ..
135 } => Key::Tab,
136
137 event::KeyEvent {
139 code: event::KeyCode::Char(c),
140 modifiers: event::KeyModifiers::ALT,
141 kind: _,
142 state: _,
143 } => Key::Alt(c),
144
145 event::KeyEvent {
146 code: event::KeyCode::Char(c),
147 modifiers: event::KeyModifiers::CONTROL,
148 kind: _,
149 state: _,
150 } => Key::Ctrl(c),
151
152 event::KeyEvent {
153 code: event::KeyCode::Char(c),
154 modifiers: event::KeyModifiers::SHIFT,
155 kind: _,
156 state: _,
157 } => Key::Shift(c),
158
159 event::KeyEvent {
160 code: event::KeyCode::Char(c),
161 ..
162 } => Key::Char(c),
163
164 _ => Key::Unknown,
165 }
166 }
167}
168
169impl Display for Key {
170 fn fmt(&self, f: &mut Formatter) -> fmt::Result {
171 match *self {
172 Key::Alt(' ') => write!(f, "alt+space"),
173 Key::Ctrl(' ') => write!(f, "ctrl+space"),
174 Key::Char(' ') => write!(f, "space"),
175 Key::Alt(c) => write!(f, "alt+{}", c),
176 Key::Ctrl(c) => write!(f, "ctrl+{}", c),
177 Key::Shift(c) => write!(f, "shift+{}", c.to_lowercase()),
178 Key::Char(c) => write!(f, "{}", c),
179 _ => write!(f, "{:?}", self),
180 }
181 }
182}