1#[cfg(feature = "serde")]
4use serde::{Deserialize, Serialize};
5
6use std::io::{Error, ErrorKind};
7use std::str;
8
9#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
11#[derive(Debug, Clone, PartialEq, Eq, Hash)]
12pub enum Event {
13 Key(Key),
15 Mouse(MouseEvent),
17 Unsupported(Vec<u8>),
19}
20
21#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
23#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
24pub enum MouseEvent {
25 Press(MouseButton, u16, u16),
29 Release(u16, u16),
33 Hold(u16, u16),
37}
38
39#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
41#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
42pub enum MouseButton {
43 Left,
45 Right,
47 Middle,
49 WheelUp,
53 WheelDown,
57 WheelLeft,
61 WheelRight,
65}
66
67#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
69#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
70pub enum Key {
71 Backspace,
73 Left,
75 ShiftLeft,
77 AltLeft,
79 CtrlLeft,
81 Right,
83 ShiftRight,
85 AltRight,
87 CtrlRight,
89 Up,
91 ShiftUp,
93 AltUp,
95 CtrlUp,
97 Down,
99 ShiftDown,
101 AltDown,
103 CtrlDown,
105 Home,
107 CtrlHome,
109 End,
111 CtrlEnd,
113 PageUp,
115 PageDown,
117 BackTab,
119 Delete,
121 Insert,
123 F(u8),
127 Char(char),
129 Alt(char),
131 Ctrl(char),
135 Null,
137 Esc,
139
140 #[doc(hidden)]
141 __IsNotComplete,
142}
143
144pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
146where
147 I: Iterator<Item = Result<u8, Error>>,
148{
149 let error = Error::new(ErrorKind::Other, "Could not parse an event");
150 match item {
151 b'\x1B' => {
152 Ok(match iter.next() {
154 Some(Ok(b'O')) => {
155 match iter.next() {
156 Some(Ok(val @ b'P'..=b'S')) => Event::Key(Key::F(1 + val - b'P')),
158 _ => return Err(error),
159 }
160 }
161 Some(Ok(b'[')) => {
162 parse_csi(iter).ok_or(error)?
164 }
165 Some(Ok(c)) => {
166 let ch = parse_utf8_char(c, iter)?;
167 Event::Key(Key::Alt(ch))
168 }
169 Some(Err(_)) | None => return Err(error),
170 })
171 }
172 b'\n' | b'\r' => Ok(Event::Key(Key::Char('\n'))),
173 b'\t' => Ok(Event::Key(Key::Char('\t'))),
174 b'\x7F' => Ok(Event::Key(Key::Backspace)),
175 c @ b'\x01'..=b'\x1A' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
176 c @ b'\x1C'..=b'\x1F' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1C + b'4') as char))),
177 b'\0' => Ok(Event::Key(Key::Null)),
178 c => Ok({
179 let ch = parse_utf8_char(c, iter)?;
180 Event::Key(Key::Char(ch))
181 }),
182 }
183}
184
185fn parse_csi<I>(iter: &mut I) -> Option<Event>
189where
190 I: Iterator<Item = Result<u8, Error>>,
191{
192 Some(match iter.next() {
193 Some(Ok(b'[')) => match iter.next() {
194 Some(Ok(val @ b'A'..=b'E')) => Event::Key(Key::F(1 + val - b'A')),
195 _ => return None,
196 },
197 Some(Ok(b'D')) => Event::Key(Key::Left),
198 Some(Ok(b'C')) => Event::Key(Key::Right),
199 Some(Ok(b'A')) => Event::Key(Key::Up),
200 Some(Ok(b'B')) => Event::Key(Key::Down),
201 Some(Ok(b'H')) => Event::Key(Key::Home),
202 Some(Ok(b'F')) => Event::Key(Key::End),
203 Some(Ok(b'Z')) => Event::Key(Key::BackTab),
204 Some(Ok(b'M')) => {
205 let mut next = || iter.next().unwrap().unwrap();
207
208 let cb = next() as i8 - 32;
209 let cx = next().saturating_sub(32) as u16;
211 let cy = next().saturating_sub(32) as u16;
212 Event::Mouse(match cb & 0b11 {
213 0 => {
214 if cb & 0x40 != 0 {
215 MouseEvent::Press(MouseButton::WheelUp, cx, cy)
216 } else {
217 MouseEvent::Press(MouseButton::Left, cx, cy)
218 }
219 }
220 1 => {
221 if cb & 0x40 != 0 {
222 MouseEvent::Press(MouseButton::WheelDown, cx, cy)
223 } else {
224 MouseEvent::Press(MouseButton::Middle, cx, cy)
225 }
226 }
227 2 => {
228 if cb & 0x40 != 0 {
229 MouseEvent::Press(MouseButton::WheelLeft, cx, cy)
230 } else {
231 MouseEvent::Press(MouseButton::Right, cx, cy)
232 }
233 }
234 3 => {
235 if cb & 0x40 != 0 {
236 MouseEvent::Press(MouseButton::WheelRight, cx, cy)
237 } else {
238 MouseEvent::Release(cx, cy)
239 }
240 }
241 _ => return None,
242 })
243 }
244 Some(Ok(b'<')) => {
245 let mut buf = Vec::new();
248 let mut c = iter.next().unwrap().unwrap();
249 while match c {
250 b'm' | b'M' => false,
251 _ => true,
252 } {
253 buf.push(c);
254 c = iter.next().unwrap().unwrap();
255 }
256 let str_buf = String::from_utf8(buf).unwrap();
257 let nums = &mut str_buf.split(';');
258
259 let cb = nums.next().unwrap().parse::<u16>().unwrap();
260 let cx = nums.next().unwrap().parse::<u16>().unwrap();
261 let cy = nums.next().unwrap().parse::<u16>().unwrap();
262
263 let event = match cb {
264 0..=2 | 64..=67 => {
265 let button = match cb {
266 0 => MouseButton::Left,
267 1 => MouseButton::Middle,
268 2 => MouseButton::Right,
269 64 => MouseButton::WheelUp,
270 65 => MouseButton::WheelDown,
271 66 => MouseButton::WheelLeft,
272 67 => MouseButton::WheelRight,
273 _ => unreachable!(),
274 };
275 match c {
276 b'M' => MouseEvent::Press(button, cx, cy),
277 b'm' => MouseEvent::Release(cx, cy),
278 _ => return None,
279 }
280 }
281 32 => MouseEvent::Hold(cx, cy),
282 3 => MouseEvent::Release(cx, cy),
283 _ => return None,
284 };
285
286 Event::Mouse(event)
287 }
288 Some(Ok(c @ b'0'..=b'9')) => {
289 let mut buf = Vec::new();
291 buf.push(c);
292 let mut c = iter.next().unwrap().unwrap();
293 while c < 64 || c > 126 {
296 buf.push(c);
297 c = iter.next().unwrap().unwrap();
298 }
299
300 match c {
301 b'M' => {
304 let str_buf = String::from_utf8(buf).unwrap();
305
306 let nums: Vec<u16> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
307
308 let cb = nums[0];
309 let cx = nums[1];
310 let cy = nums[2];
311
312 let event = match cb {
313 32 => MouseEvent::Press(MouseButton::Left, cx, cy),
314 33 => MouseEvent::Press(MouseButton::Middle, cx, cy),
315 34 => MouseEvent::Press(MouseButton::Right, cx, cy),
316 35 => MouseEvent::Release(cx, cy),
317 64 => MouseEvent::Hold(cx, cy),
318 96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
319 _ => return None,
320 };
321
322 Event::Mouse(event)
323 }
324 b'~' => {
326 let str_buf = String::from_utf8(buf).unwrap();
327
328 let nums: Vec<u8> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
331
332 if nums.is_empty() {
333 return None;
334 }
335
336 if nums.len() > 1 {
339 return None;
340 }
341
342 match nums[0] {
343 1 | 7 => Event::Key(Key::Home),
344 2 => Event::Key(Key::Insert),
345 3 => Event::Key(Key::Delete),
346 4 | 8 => Event::Key(Key::End),
347 5 => Event::Key(Key::PageUp),
348 6 => Event::Key(Key::PageDown),
349 v @ 11..=15 => Event::Key(Key::F(v - 10)),
350 v @ 17..=21 => Event::Key(Key::F(v - 11)),
351 v @ 23..=24 => Event::Key(Key::F(v - 12)),
352 _ => return None,
353 }
354 }
355 b'A' | b'B' | b'C' | b'D' | b'F' | b'H' => {
356 let str_buf = String::from_utf8(buf).unwrap();
357
358 let nums: Vec<u8> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
361
362 if !(nums.len() == 2 && nums[0] == 1) {
363 return None;
364 }
365
366 match nums[1] {
367 2 => {
368 match c {
370 b'D' => Event::Key(Key::ShiftLeft),
371 b'C' => Event::Key(Key::ShiftRight),
372 b'A' => Event::Key(Key::ShiftUp),
373 b'B' => Event::Key(Key::ShiftDown),
374 _ => return None,
375 }
376 }
377 3 => {
378 match c {
380 b'D' => Event::Key(Key::AltLeft),
381 b'C' => Event::Key(Key::AltRight),
382 b'A' => Event::Key(Key::AltUp),
383 b'B' => Event::Key(Key::AltDown),
384 _ => return None,
385 }
386 }
387 5 => {
388 match c {
390 b'D' => Event::Key(Key::CtrlLeft),
391 b'C' => Event::Key(Key::CtrlRight),
392 b'A' => Event::Key(Key::CtrlUp),
393 b'B' => Event::Key(Key::CtrlDown),
394 b'H' => Event::Key(Key::CtrlHome),
395 b'F' => Event::Key(Key::CtrlEnd),
396 _ => return None,
397 }
398 }
399 _ => return None,
400 }
401 }
402 _ => return None,
403 }
404 }
405 _ => return None,
406 })
407}
408
409fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
411where
412 I: Iterator<Item = Result<u8, Error>>,
413{
414 let error = Err(Error::new(
415 ErrorKind::Other,
416 "Input character is not valid UTF-8",
417 ));
418 if c.is_ascii() {
419 Ok(c as char)
420 } else {
421 let bytes = &mut Vec::new();
422 bytes.push(c);
423
424 loop {
425 match iter.next() {
426 Some(Ok(next)) => {
427 bytes.push(next);
428 if let Ok(st) = str::from_utf8(bytes) {
429 return Ok(st.chars().next().unwrap());
430 }
431 if bytes.len() >= 4 {
432 return error;
433 }
434 }
435 _ => return error,
436 }
437 }
438 }
439}
440
441#[cfg(test)]
442#[test]
443fn test_parse_utf8() {
444 let st = "abcéŷ¤£€ù%323";
445 let ref mut bytes = st.bytes().map(|x| Ok(x));
446 let chars = st.chars();
447 for c in chars {
448 let b = bytes.next().unwrap().unwrap();
449 assert!(c == parse_utf8_char(b, bytes).unwrap());
450 }
451}