oo_ide/input/
key_event.rs1use crate::prelude::*;
2
3use input::{Key, Modifiers};
4
5#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
6pub struct KeyEvent {
7 pub modifiers: Modifiers,
8 pub key: Key,
9}
10
11impl TryFrom<crossterm::event::KeyEvent> for KeyEvent {
12 type Error = ();
13
14 fn try_from(event: crossterm::event::KeyEvent) -> Result<Self, Self::Error> {
15 Ok(KeyEvent {
16 modifiers: event.modifiers.into(),
17 key: Key::try_from(event.code)?,
18 })
19 }
20}
21
22impl std::fmt::Display for KeyEvent {
23 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
24 if self.modifiers.is_empty() {
25 write!(f, "{}", self.key)
26 } else {
27 write!(f, "{}+{}", self.modifiers, self.key)
28 }
29 }
30}
31
32#[cfg(test)]
33mod tests {
34 use super::*;
35 use crossterm::event::{KeyCode, KeyModifiers};
36
37 fn ct_key(
38 code: KeyCode,
39 mods: KeyModifiers,
40 ) -> crossterm::event::KeyEvent {
41 crossterm::event::KeyEvent::new(code, mods)
42 }
43
44 #[test]
46 fn try_from_char_no_mods() {
47 let ev = KeyEvent::try_from(ct_key(KeyCode::Char('a'), KeyModifiers::empty()))
48 .unwrap();
49 assert_eq!(ev.key, Key::Char('a'));
50 assert!(ev.modifiers.is_empty());
51 }
52
53 #[test]
54 fn try_from_char_with_ctrl() {
55 let ev =
56 KeyEvent::try_from(ct_key(KeyCode::Char('s'), KeyModifiers::CONTROL)).unwrap();
57 assert_eq!(ev.key, Key::Char('s'));
58 assert!(ev.modifiers.contains(Modifiers::CTRL));
59 }
60
61 #[test]
62 fn try_from_enter_with_shift() {
63 let ev = KeyEvent::try_from(ct_key(KeyCode::Enter, KeyModifiers::SHIFT)).unwrap();
64 assert_eq!(ev.key, Key::Enter);
65 assert!(ev.modifiers.contains(Modifiers::SHIFT));
66 }
67
68 #[test]
69 fn try_from_unknown_key_is_err() {
70 assert!(
71 KeyEvent::try_from(ct_key(KeyCode::Null, KeyModifiers::empty())).is_err()
72 );
73 }
74
75 #[test]
77 fn display_no_modifiers() {
78 let ev = KeyEvent {
79 modifiers: Modifiers::empty(),
80 key: Key::Enter,
81 };
82 assert_eq!(ev.to_string(), "Enter");
83 }
84
85 #[test]
86 fn display_ctrl_modifier() {
87 let ev = KeyEvent {
88 modifiers: Modifiers::CTRL,
89 key: Key::Char('s'),
90 };
91 assert_eq!(ev.to_string(), "Ctrl+s");
92 }
93
94 #[test]
95 fn display_ctrl_shift_modifier() {
96 let ev = KeyEvent {
97 modifiers: Modifiers::CTRL | Modifiers::SHIFT,
98 key: Key::ArrowUp,
99 };
100 assert_eq!(ev.to_string(), "Ctrl+Shift+ArrowUp");
101 }
102
103 #[test]
104 fn display_alt_modifier() {
105 let ev = KeyEvent {
106 modifiers: Modifiers::ALT,
107 key: Key::F(4),
108 };
109 assert_eq!(ev.to_string(), "Alt+F4");
110 }
111
112 #[test]
114 fn key_event_clone_eq() {
115 let ev = KeyEvent {
116 modifiers: Modifiers::CTRL,
117 key: Key::Char('c'),
118 };
119 assert_eq!(ev.clone(), ev);
120 }
121
122 #[test]
123 fn key_event_hash() {
124 use std::collections::HashSet;
125 let ev = KeyEvent {
126 modifiers: Modifiers::CTRL,
127 key: Key::Char('c'),
128 };
129 let mut s = HashSet::new();
130 s.insert(ev);
131 assert!(s.contains(&ev));
132 }
133}