leetcode_tui_config/
key.rs

1use crossterm::event::{self, KeyEvent, KeyEventState, KeyModifiers};
2use std::fmt;
3
4/// Represents an key.
5#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
6pub enum Key {
7    /// Both Enter (or Return) and numpad Enter
8    Enter,
9    /// Tabulation key
10    Tab,
11    /// Backspace key
12    Backspace,
13    /// Escape key
14    Esc,
15
16    /// Left arrow
17    Left,
18    /// Right arrow
19    Right,
20    /// Up arrow
21    Up,
22    /// Down arrow
23    Down,
24
25    /// Insert key
26    Ins,
27    /// Delete key
28    Delete,
29    /// Home key
30    Home,
31    /// End key
32    End,
33    /// Page Up key
34    PageUp,
35    /// Page Down key
36    PageDown,
37
38    /// F0 key
39    F0,
40    /// F1 key
41    F1,
42    /// F2 key
43    F2,
44    /// F3 key
45    F3,
46    /// F4 key
47    F4,
48    /// F5 key
49    F5,
50    /// F6 key
51    F6,
52    /// F7 key
53    F7,
54    /// F8 key
55    F8,
56    /// F9 key
57    F9,
58    /// F10 key
59    F10,
60    /// F11 key
61    F11,
62    /// F12 key
63    F12,
64    Char(char),
65    Ctrl(char),
66    Alt(char),
67    Unknown,
68}
69
70impl Key {
71    /// Returns the function key corresponding to the given number
72    ///
73    /// 1 -> F1, etc...
74    ///
75    /// # Panics
76    ///
77    /// If `n == 0 || n > 12`
78    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            // First check for char + modifier
211            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}