1use super::{Input, Key};
2use ratatui_termion::termion::event::{Event, Key as KeyEvent, MouseButton, MouseEvent};
3
4impl From<Event> for Input {
5 fn from(event: Event) -> Self {
7 match event {
8 Event::Key(key) => Self::from(key),
9 Event::Mouse(mouse) => Self::from(mouse),
10 _ => Self::default(),
11 }
12 }
13}
14
15impl From<KeyEvent> for Input {
16 fn from(key: KeyEvent) -> Self {
28 let (ctrl, alt, shift) = match key {
29 KeyEvent::Ctrl(_)
30 | KeyEvent::CtrlUp
31 | KeyEvent::CtrlRight
32 | KeyEvent::CtrlDown
33 | KeyEvent::CtrlLeft
34 | KeyEvent::CtrlHome
35 | KeyEvent::CtrlEnd => (true, false, false),
36 KeyEvent::Alt(_)
37 | KeyEvent::AltUp
38 | KeyEvent::AltRight
39 | KeyEvent::AltDown
40 | KeyEvent::AltLeft => (false, true, false),
41 KeyEvent::ShiftUp
42 | KeyEvent::ShiftRight
43 | KeyEvent::ShiftDown
44 | KeyEvent::ShiftLeft => (false, false, true),
45 _ => (false, false, false),
46 };
47
48 let key = match key {
49 KeyEvent::Char('\n' | '\r') => Key::Enter,
50 KeyEvent::Char(c) | KeyEvent::Ctrl(c) | KeyEvent::Alt(c) => Key::Char(c),
51 KeyEvent::Backspace => Key::Backspace,
52 KeyEvent::Left | KeyEvent::CtrlLeft | KeyEvent::AltLeft | KeyEvent::ShiftLeft => {
53 Key::Left
54 }
55 KeyEvent::Right | KeyEvent::CtrlRight | KeyEvent::AltRight | KeyEvent::ShiftRight => {
56 Key::Right
57 }
58 KeyEvent::Up | KeyEvent::CtrlUp | KeyEvent::AltUp | KeyEvent::ShiftUp => Key::Up,
59 KeyEvent::Down | KeyEvent::CtrlDown | KeyEvent::AltDown | KeyEvent::ShiftDown => {
60 Key::Down
61 }
62 KeyEvent::Home | KeyEvent::CtrlHome => Key::Home,
63 KeyEvent::End | KeyEvent::CtrlEnd => Key::End,
64 KeyEvent::PageUp => Key::PageUp,
65 KeyEvent::PageDown => Key::PageDown,
66 KeyEvent::BackTab => Key::Tab,
67 KeyEvent::Delete => Key::Delete,
68 KeyEvent::Esc => Key::Esc,
69 KeyEvent::F(x) => Key::F(x),
70 _ => Key::Null,
71 };
72
73 Input {
74 key,
75 ctrl,
76 alt,
77 shift,
78 }
79 }
80}
81
82impl From<MouseButton> for Key {
83 fn from(button: MouseButton) -> Self {
85 match button {
86 MouseButton::WheelUp => Key::MouseScrollUp,
87 MouseButton::WheelDown => Key::MouseScrollDown,
88 _ => Key::Null,
89 }
90 }
91}
92
93impl From<MouseEvent> for Input {
94 fn from(mouse: MouseEvent) -> Self {
96 let key = if let MouseEvent::Press(button, ..) = mouse {
97 Key::from(button)
98 } else {
99 Key::Null
100 };
101 Self {
102 key,
103 ctrl: false,
104 alt: false,
105 shift: false,
106 }
107 }
108}
109
110#[cfg(test)]
111mod tests {
112 use super::*;
113 use crate::input::tests::input;
114
115 #[test]
116 fn key_to_input() {
117 for (from, to) in [
118 (
119 KeyEvent::Char('a'),
120 input(Key::Char('a'), false, false, false),
121 ),
122 (
123 KeyEvent::Ctrl('a'),
124 input(Key::Char('a'), true, false, false),
125 ),
126 (
127 KeyEvent::Alt('a'),
128 input(Key::Char('a'), false, true, false),
129 ),
130 (KeyEvent::Char('\n'), input(Key::Enter, false, false, false)),
131 (KeyEvent::Char('\r'), input(Key::Enter, false, false, false)),
132 (KeyEvent::F(1), input(Key::F(1), false, false, false)),
133 (KeyEvent::BackTab, input(Key::Tab, false, false, false)),
134 (KeyEvent::Null, input(Key::Null, false, false, false)),
135 #[cfg(feature = "termion")]
136 (KeyEvent::ShiftDown, input(Key::Down, false, false, true)),
137 #[cfg(feature = "termion")]
138 (KeyEvent::AltUp, input(Key::Up, false, true, false)),
139 #[cfg(feature = "termion")]
140 (KeyEvent::CtrlLeft, input(Key::Left, true, false, false)),
141 #[cfg(feature = "termion")]
142 (KeyEvent::CtrlHome, input(Key::Home, true, false, false)),
143 ] {
144 assert_eq!(Input::from(from), to, "{:?} -> {:?}", from, to);
145 }
146 }
147
148 #[test]
149 fn mouse_to_input() {
150 for (from, to) in [
151 (
152 MouseEvent::Press(MouseButton::WheelDown, 1, 1),
153 input(Key::MouseScrollDown, false, false, false),
154 ),
155 (
156 MouseEvent::Press(MouseButton::WheelUp, 1, 1),
157 input(Key::MouseScrollUp, false, false, false),
158 ),
159 (
160 MouseEvent::Press(MouseButton::Left, 1, 1),
161 input(Key::Null, false, false, false),
162 ),
163 (
164 MouseEvent::Release(1, 1),
165 input(Key::Null, false, false, false),
166 ),
167 (
168 MouseEvent::Hold(1, 1),
169 input(Key::Null, false, false, false),
170 ),
171 ] {
172 assert_eq!(Input::from(from), to, "{:?} -> {:?}", from, to);
173 }
174 }
175
176 #[test]
177 fn event_to_input() {
178 for (from, to) in [
179 (
180 Event::Key(KeyEvent::Char('a')),
181 input(Key::Char('a'), false, false, false),
182 ),
183 (
184 Event::Mouse(MouseEvent::Press(MouseButton::WheelDown, 1, 1)),
185 input(Key::MouseScrollDown, false, false, false),
186 ),
187 (
188 Event::Unsupported(vec![]),
189 input(Key::Null, false, false, false),
190 ),
191 ] {
192 assert_eq!(Input::from(from.clone()), to, "{:?} -> {:?}", from, to);
193 }
194 }
195}