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