npcore/tui/inputs/
key.rs

1use std::fmt::{self, Display, Formatter};
2
3use crossterm::event;
4
5/// Represents an key.
6#[derive(PartialEq, Eq, Clone, Copy, Hash, Debug)]
7pub enum Key {
8    /// Both Enter (or Return) and numpad Enter
9    Enter,
10    /// Tabulation key
11    Tab,
12    /// Backspace key
13    Backspace,
14    /// Escape key
15    Esc,
16
17    /// Left arrow
18    Left,
19    /// Right arrow
20    Right,
21    /// Up arrow
22    Up,
23    /// Down arrow
24    Down,
25
26    /// Insert key
27    Ins,
28    /// Delete key
29    Delete,
30    /// Home key
31    Home,
32    /// End key
33    End,
34    /// Page Up key
35    PageUp,
36    /// Page Down key
37    PageDown,
38
39    /// F0 key
40    F0,
41    /// F1 key
42    F1,
43    /// F2 key
44    F2,
45    /// F3 key
46    F3,
47    /// F4 key
48    F4,
49    /// F5 key
50    F5,
51    /// F6 key
52    F6,
53    /// F7 key
54    F7,
55    /// F8 key
56    F8,
57    /// F9 key
58    F9,
59    /// F10 key
60    F10,
61    /// F11 key
62    F11,
63    /// F12 key
64    F12,
65    Char(char),
66    Ctrl(char),
67    Alt(char),
68    Unknown,
69}
70
71impl Key {
72    /// If exit
73    pub fn is_exit(&self) -> bool {
74        matches!(self, Key::Ctrl('c') | Key::Char('q') | Key::Esc)
75    }
76
77    pub fn is_stop(&self) -> bool {
78        matches!(self, Key::Ctrl('e'))
79    }
80
81    /// Returns the function key corresponding to the given number
82    ///
83    /// 1 -> F1, etc...
84    ///
85    /// # Panics
86    ///
87    /// If `n == 0 || n > 12`
88    pub fn from_f(n: u8) -> Key {
89        match n {
90            0 => Key::F0,
91            1 => Key::F1,
92            2 => Key::F2,
93            3 => Key::F3,
94            4 => Key::F4,
95            5 => Key::F5,
96            6 => Key::F6,
97            7 => Key::F7,
98            8 => Key::F8,
99            9 => Key::F9,
100            10 => Key::F10,
101            11 => Key::F11,
102            12 => Key::F12,
103            _ => panic!("unknown function key: F{}", n),
104        }
105    }
106}
107
108impl Display for Key {
109    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
110        match *self {
111            Key::Alt(' ') => write!(f, "<Alt+Space>"),
112            Key::Ctrl(' ') => write!(f, "<Ctrl+Space>"),
113            Key::Char(' ') => write!(f, "<Space>"),
114            Key::Alt(c) => write!(f, "<Alt+{}>", c),
115            Key::Ctrl(c) => write!(f, "<Ctrl+{}>", c),
116            Key::Char(c) => write!(f, "<{}>", c),
117            _ => write!(f, "<{:?}>", self),
118        }
119    }
120}
121
122impl From<event::KeyEvent> for Key {
123    fn from(key_event: event::KeyEvent) -> Self {
124        match key_event {
125            event::KeyEvent {
126                code: event::KeyCode::Esc,
127                ..
128            } => Key::Esc,
129            event::KeyEvent {
130                code: event::KeyCode::Backspace,
131                ..
132            } => Key::Backspace,
133            event::KeyEvent {
134                code: event::KeyCode::Left,
135                ..
136            } => Key::Left,
137            event::KeyEvent {
138                code: event::KeyCode::Right,
139                ..
140            } => Key::Right,
141            event::KeyEvent {
142                code: event::KeyCode::Up,
143                ..
144            } => Key::Up,
145            event::KeyEvent {
146                code: event::KeyCode::Down,
147                ..
148            } => Key::Down,
149            event::KeyEvent {
150                code: event::KeyCode::Home,
151                ..
152            } => Key::Home,
153            event::KeyEvent {
154                code: event::KeyCode::End,
155                ..
156            } => Key::End,
157            event::KeyEvent {
158                code: event::KeyCode::PageUp,
159                ..
160            } => Key::PageUp,
161            event::KeyEvent {
162                code: event::KeyCode::PageDown,
163                ..
164            } => Key::PageDown,
165            event::KeyEvent {
166                code: event::KeyCode::Delete,
167                ..
168            } => Key::Delete,
169            event::KeyEvent {
170                code: event::KeyCode::Insert,
171                ..
172            } => Key::Ins,
173            event::KeyEvent {
174                code: event::KeyCode::F(n),
175                ..
176            } => Key::from_f(n),
177            event::KeyEvent {
178                code: event::KeyCode::Enter,
179                ..
180            } => Key::Enter,
181            event::KeyEvent {
182                code: event::KeyCode::Tab,
183                ..
184            } => Key::Tab,
185
186            // First check for char + modifier
187            event::KeyEvent {
188                code: event::KeyCode::Char(c),
189                modifiers: event::KeyModifiers::ALT,
190                ..
191            } => Key::Alt(c),
192            event::KeyEvent {
193                code: event::KeyCode::Char(c),
194                modifiers: event::KeyModifiers::CONTROL,
195                ..
196            } => Key::Ctrl(c),
197
198            event::KeyEvent {
199                code: event::KeyCode::Char(c),
200                ..
201            } => Key::Char(c),
202
203            _ => Key::Unknown,
204        }
205    }
206}