1 use std::io;
2 
3 use crate::{
4     event::{Event, KeyCode, KeyEvent, KeyModifiers, MouseButton, MouseEvent, MouseEventKind},
5     ErrorKind, Result,
6 };
7 
8 use super::super::super::InternalEvent;
9 
10 // Event parsing
11 //
12 // This code (& previous one) are kind of ugly. We have to think about this,
13 // because it's really not maintainable, no tests, etc.
14 //
15 // Every fn returns Result<Option<InputEvent>>
16 //
17 // Ok(None) -> wait for more bytes
18 // Err(_) -> failed to parse event, clear the buffer
19 // Ok(Some(event)) -> we have event, clear the buffer
20 //
21 
could_not_parse_event_error() -> ErrorKind22 fn could_not_parse_event_error() -> ErrorKind {
23     io::Error::new(io::ErrorKind::Other, "Could not parse an event.")
24 }
25 
parse_event(buffer: &[u8], input_available: bool) -> Result<Option<InternalEvent>>26 pub(crate) fn parse_event(buffer: &[u8], input_available: bool) -> Result<Option<InternalEvent>> {
27     if buffer.is_empty() {
28         return Ok(None);
29     }
30 
31     match buffer[0] {
32         b'\x1B' => {
33             if buffer.len() == 1 {
34                 if input_available {
35                     // Possible Esc sequence
36                     Ok(None)
37                 } else {
38                     Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Esc.into()))))
39                 }
40             } else {
41                 match buffer[1] {
42                     b'O' => {
43                         if buffer.len() == 2 {
44                             Ok(None)
45                         } else {
46                             match buffer[2] {
47                                 // F1-F4
48                                 val @ b'P'..=b'S' => Ok(Some(InternalEvent::Event(Event::Key(
49                                     KeyCode::F(1 + val - b'P').into(),
50                                 )))),
51                                 _ => Err(could_not_parse_event_error()),
52                             }
53                         }
54                     }
55                     b'[' => parse_csi(buffer),
56                     b'\x1B' => Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Esc.into())))),
57                     _ => parse_event(&buffer[1..], input_available).map(|event_option| {
58                         event_option.map(|event| {
59                             if let InternalEvent::Event(Event::Key(key_event)) = event {
60                                 let mut alt_key_event = key_event;
61                                 alt_key_event.modifiers |= KeyModifiers::ALT;
62                                 InternalEvent::Event(Event::Key(alt_key_event))
63                             } else {
64                                 event
65                             }
66                         })
67                     }),
68                 }
69             }
70         }
71         b'\r' => Ok(Some(InternalEvent::Event(Event::Key(
72             KeyCode::Enter.into(),
73         )))),
74         // Issue #371: \n = 0xA, which is also the keycode for Ctrl+J. The only reason we get
75         // newlines as input is because the terminal converts \r into \n for us. When we
76         // enter raw mode, we disable that, so \n no longer has any meaning - it's better to
77         // use Ctrl+J. Waiting to handle it here means it gets picked up later
78         b'\n' if !crate::terminal::sys::is_raw_mode_enabled() => Ok(Some(InternalEvent::Event(
79             Event::Key(KeyCode::Enter.into()),
80         ))),
81         b'\t' => Ok(Some(InternalEvent::Event(Event::Key(KeyCode::Tab.into())))),
82         b'\x7F' => Ok(Some(InternalEvent::Event(Event::Key(
83             KeyCode::Backspace.into(),
84         )))),
85         c @ b'\x01'..=b'\x1A' => Ok(Some(InternalEvent::Event(Event::Key(KeyEvent::new(
86             KeyCode::Char((c as u8 - 0x1 + b'a') as char),
87             KeyModifiers::CONTROL,
88         ))))),
89         c @ b'\x1C'..=b'\x1F' => Ok(Some(InternalEvent::Event(Event::Key(KeyEvent::new(
90             KeyCode::Char((c as u8 - 0x1C + b'4') as char),
91             KeyModifiers::CONTROL,
92         ))))),
93         b'\0' => Ok(Some(InternalEvent::Event(Event::Key(KeyEvent::new(
94             KeyCode::Char(' '),
95             KeyModifiers::CONTROL,
96         ))))),
97         _ => parse_utf8_char(buffer).map(|maybe_char| {
98             maybe_char
99                 .map(KeyCode::Char)
100                 .map(char_code_to_event)
101                 .map(Event::Key)
102                 .map(InternalEvent::Event)
103         }),
104     }
105 }
106 
107 // converts KeyCode to KeyEvent (adds shift modifier in case of uppercase characters)
char_code_to_event(code: KeyCode) -> KeyEvent108 fn char_code_to_event(code: KeyCode) -> KeyEvent {
109     let modifiers = match code {
110         KeyCode::Char(c) if c.is_uppercase() => KeyModifiers::SHIFT,
111         _ => KeyModifiers::empty(),
112     };
113     KeyEvent::new(code, modifiers)
114 }
115 
parse_csi(buffer: &[u8]) -> Result<Option<InternalEvent>>116 pub(crate) fn parse_csi(buffer: &[u8]) -> Result<Option<InternalEvent>> {
117     assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
118 
119     if buffer.len() == 2 {
120         return Ok(None);
121     }
122 
123     let input_event = match buffer[2] {
124         b'[' => {
125             if buffer.len() == 3 {
126                 None
127             } else {
128                 match buffer[3] {
129                     // NOTE (@imdaveho): cannot find when this occurs;
130                     // having another '[' after ESC[ not a likely scenario
131                     val @ b'A'..=b'E' => Some(Event::Key(KeyCode::F(1 + val - b'A').into())),
132                     _ => return Err(could_not_parse_event_error()),
133                 }
134             }
135         }
136         b'D' => Some(Event::Key(KeyCode::Left.into())),
137         b'C' => Some(Event::Key(KeyCode::Right.into())),
138         b'A' => Some(Event::Key(KeyCode::Up.into())),
139         b'B' => Some(Event::Key(KeyCode::Down.into())),
140         b'H' => Some(Event::Key(KeyCode::Home.into())),
141         b'F' => Some(Event::Key(KeyCode::End.into())),
142         b'Z' => Some(Event::Key(KeyEvent {
143             code: KeyCode::BackTab,
144             modifiers: KeyModifiers::SHIFT,
145         })),
146         b'M' => return parse_csi_normal_mouse(buffer),
147         b'<' => return parse_csi_sgr_mouse(buffer),
148         b'0'..=b'9' => {
149             // Numbered escape code.
150             if buffer.len() == 3 {
151                 None
152             } else {
153                 // The final byte of a CSI sequence can be in the range 64-126, so
154                 // let's keep reading anything else.
155                 let last_byte = *buffer.last().unwrap();
156                 if !(64..=126).contains(&last_byte) {
157                     None
158                 } else {
159                     match buffer[buffer.len() - 1] {
160                         b'M' => return parse_csi_rxvt_mouse(buffer),
161                         b'~' => return parse_csi_special_key_code(buffer),
162                         b'R' => return parse_csi_cursor_position(buffer),
163                         _ => return parse_csi_modifier_key_code(buffer),
164                     }
165                 }
166             }
167         }
168         _ => return Err(could_not_parse_event_error()),
169     };
170 
171     Ok(input_event.map(InternalEvent::Event))
172 }
173 
next_parsed<T>(iter: &mut dyn Iterator<Item = &str>) -> Result<T> where T: std::str::FromStr,174 pub(crate) fn next_parsed<T>(iter: &mut dyn Iterator<Item = &str>) -> Result<T>
175 where
176     T: std::str::FromStr,
177 {
178     iter.next()
179         .ok_or_else(could_not_parse_event_error)?
180         .parse::<T>()
181         .map_err(|_| could_not_parse_event_error())
182 }
183 
parse_csi_cursor_position(buffer: &[u8]) -> Result<Option<InternalEvent>>184 pub(crate) fn parse_csi_cursor_position(buffer: &[u8]) -> Result<Option<InternalEvent>> {
185     // ESC [ Cy ; Cx R
186     //   Cy - cursor row number (starting from 1)
187     //   Cx - cursor column number (starting from 1)
188     assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
189     assert!(buffer.ends_with(&[b'R']));
190 
191     let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
192         .map_err(|_| could_not_parse_event_error())?;
193 
194     let mut split = s.split(';');
195 
196     let y = next_parsed::<u16>(&mut split)? - 1;
197     let x = next_parsed::<u16>(&mut split)? - 1;
198 
199     Ok(Some(InternalEvent::CursorPosition(x, y)))
200 }
201 
parse_modifiers(mask: u8) -> KeyModifiers202 fn parse_modifiers(mask: u8) -> KeyModifiers {
203     let modifier_mask = mask.saturating_sub(1);
204     let mut modifiers = KeyModifiers::empty();
205     if modifier_mask & 1 != 0 {
206         modifiers |= KeyModifiers::SHIFT;
207     }
208     if modifier_mask & 2 != 0 {
209         modifiers |= KeyModifiers::ALT;
210     }
211     if modifier_mask & 4 != 0 {
212         modifiers |= KeyModifiers::CONTROL;
213     }
214     modifiers
215 }
216 
parse_csi_modifier_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>>217 pub(crate) fn parse_csi_modifier_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>> {
218     assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
219 
220     let modifier_mask = buffer[buffer.len() - 2];
221     let key = buffer[buffer.len() - 1];
222 
223     let modifiers = parse_modifiers(modifier_mask);
224 
225     let keycode = match key {
226         b'A' => KeyCode::Up,
227         b'B' => KeyCode::Down,
228         b'C' => KeyCode::Right,
229         b'D' => KeyCode::Left,
230         b'F' => KeyCode::End,
231         b'H' => KeyCode::Home,
232         b'P' => KeyCode::F(1),
233         b'Q' => KeyCode::F(2),
234         b'R' => KeyCode::F(3),
235         b'S' => KeyCode::F(4),
236         _ => return Err(could_not_parse_event_error()),
237     };
238 
239     let input_event = Event::Key(KeyEvent::new(keycode, modifiers));
240 
241     Ok(Some(InternalEvent::Event(input_event)))
242 }
243 
parse_csi_special_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>>244 pub(crate) fn parse_csi_special_key_code(buffer: &[u8]) -> Result<Option<InternalEvent>> {
245     assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
246     assert!(buffer.ends_with(&[b'~']));
247 
248     let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
249         .map_err(|_| could_not_parse_event_error())?;
250     let mut split = s.split(';');
251 
252     // This CSI sequence can be a list of semicolon-separated numbers.
253     let first = next_parsed::<u8>(&mut split)?;
254 
255     let modifiers = if let Ok(modifier_mask) = next_parsed::<u8>(&mut split) {
256         parse_modifiers(modifier_mask)
257     } else {
258         KeyModifiers::NONE
259     };
260 
261     let keycode = match first {
262         1 | 7 => KeyCode::Home,
263         2 => KeyCode::Insert,
264         3 => KeyCode::Delete,
265         4 | 8 => KeyCode::End,
266         5 => KeyCode::PageUp,
267         6 => KeyCode::PageDown,
268         v @ 11..=15 => KeyCode::F(v - 10),
269         v @ 17..=21 => KeyCode::F(v - 11),
270         v @ 23..=26 => KeyCode::F(v - 12),
271         v @ 28..=29 => KeyCode::F(v - 15),
272         v @ 31..=34 => KeyCode::F(v - 17),
273         _ => return Err(could_not_parse_event_error()),
274     };
275 
276     let input_event = Event::Key(KeyEvent::new(keycode, modifiers));
277 
278     Ok(Some(InternalEvent::Event(input_event)))
279 }
280 
parse_csi_rxvt_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>>281 pub(crate) fn parse_csi_rxvt_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>> {
282     // rxvt mouse encoding:
283     // ESC [ Cb ; Cx ; Cy ; M
284 
285     assert!(buffer.starts_with(&[b'\x1B', b'['])); // ESC [
286     assert!(buffer.ends_with(&[b'M']));
287 
288     let s = std::str::from_utf8(&buffer[2..buffer.len() - 1])
289         .map_err(|_| could_not_parse_event_error())?;
290     let mut split = s.split(';');
291 
292     let cb = next_parsed::<u8>(&mut split)?
293         .checked_sub(32)
294         .ok_or_else(could_not_parse_event_error)?;
295     let (kind, modifiers) = parse_cb(cb)?;
296 
297     let cx = next_parsed::<u16>(&mut split)? - 1;
298     let cy = next_parsed::<u16>(&mut split)? - 1;
299 
300     Ok(Some(InternalEvent::Event(Event::Mouse(MouseEvent {
301         kind,
302         column: cx,
303         row: cy,
304         modifiers,
305     }))))
306 }
307 
parse_csi_normal_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>>308 pub(crate) fn parse_csi_normal_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>> {
309     // Normal mouse encoding: ESC [ M CB Cx Cy (6 characters only).
310 
311     assert!(buffer.starts_with(&[b'\x1B', b'[', b'M'])); // ESC [ M
312 
313     if buffer.len() < 6 {
314         return Ok(None);
315     }
316 
317     let cb = buffer[3]
318         .checked_sub(32)
319         .ok_or_else(could_not_parse_event_error)?;
320     let (kind, modifiers) = parse_cb(cb)?;
321 
322     // See http://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking
323     // The upper left character position on the terminal is denoted as 1,1.
324     // Subtract 1 to keep it synced with cursor
325     let cx = u16::from(buffer[4].saturating_sub(32)) - 1;
326     let cy = u16::from(buffer[5].saturating_sub(32)) - 1;
327 
328     Ok(Some(InternalEvent::Event(Event::Mouse(MouseEvent {
329         kind,
330         column: cx,
331         row: cy,
332         modifiers,
333     }))))
334 }
335 
parse_csi_sgr_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>>336 pub(crate) fn parse_csi_sgr_mouse(buffer: &[u8]) -> Result<Option<InternalEvent>> {
337     // ESC [ < Cb ; Cx ; Cy (;) (M or m)
338 
339     assert!(buffer.starts_with(&[b'\x1B', b'[', b'<'])); // ESC [ <
340 
341     if !buffer.ends_with(&[b'm']) && !buffer.ends_with(&[b'M']) {
342         return Ok(None);
343     }
344 
345     let s = std::str::from_utf8(&buffer[3..buffer.len() - 1])
346         .map_err(|_| could_not_parse_event_error())?;
347     let mut split = s.split(';');
348 
349     let cb = next_parsed::<u8>(&mut split)?;
350     let (kind, modifiers) = parse_cb(cb)?;
351 
352     // See http://www.xfree86.org/current/ctlseqs.html#Mouse%20Tracking
353     // The upper left character position on the terminal is denoted as 1,1.
354     // Subtract 1 to keep it synced with cursor
355     let cx = next_parsed::<u16>(&mut split)? - 1;
356     let cy = next_parsed::<u16>(&mut split)? - 1;
357 
358     // When button 3 in Cb is used to represent mouse release, you can't tell which button was
359     // released. SGR mode solves this by having the sequence end with a lowercase m if it's a
360     // button release and an uppercase M if it's a buton press.
361     //
362     // We've already checked that the last character is a lowercase or uppercase M at the start of
363     // this function, so we just need one if.
364     let kind = if buffer.last() == Some(&b'm') {
365         match kind {
366             MouseEventKind::Down(button) => MouseEventKind::Up(button),
367             other => other,
368         }
369     } else {
370         kind
371     };
372 
373     Ok(Some(InternalEvent::Event(Event::Mouse(MouseEvent {
374         kind,
375         column: cx,
376         row: cy,
377         modifiers,
378     }))))
379 }
380 
381 /// Cb is the byte of a mouse input that contains the button being used, the key modifiers being
382 /// held and whether the mouse is dragging or not.
383 ///
384 /// Bit layout of cb, from low to high:
385 ///
386 /// - button number
387 /// - button number
388 /// - shift
389 /// - meta (alt)
390 /// - control
391 /// - mouse is dragging
392 /// - button number
393 /// - button number
parse_cb(cb: u8) -> Result<(MouseEventKind, KeyModifiers)>394 fn parse_cb(cb: u8) -> Result<(MouseEventKind, KeyModifiers)> {
395     let button_number = (cb & 0b0000_0011) | ((cb & 0b1100_0000) >> 4);
396     let dragging = cb & 0b0010_0000 == 0b0010_0000;
397 
398     let kind = match (button_number, dragging) {
399         (0, false) => MouseEventKind::Down(MouseButton::Left),
400         (1, false) => MouseEventKind::Down(MouseButton::Middle),
401         (2, false) => MouseEventKind::Down(MouseButton::Right),
402         (0, true) => MouseEventKind::Drag(MouseButton::Left),
403         (1, true) => MouseEventKind::Drag(MouseButton::Middle),
404         (2, true) => MouseEventKind::Drag(MouseButton::Right),
405         (3, false) => MouseEventKind::Up(MouseButton::Left),
406         (3, true) | (4, true) | (5, true) => MouseEventKind::Moved,
407         (4, false) => MouseEventKind::ScrollUp,
408         (5, false) => MouseEventKind::ScrollDown,
409         // We do not support other buttons.
410         _ => return Err(could_not_parse_event_error()),
411     };
412 
413     let mut modifiers = KeyModifiers::empty();
414 
415     if cb & 0b0000_0100 == 0b0000_0100 {
416         modifiers |= KeyModifiers::SHIFT;
417     }
418     if cb & 0b0000_1000 == 0b0000_1000 {
419         modifiers |= KeyModifiers::ALT;
420     }
421     if cb & 0b0001_0000 == 0b0001_0000 {
422         modifiers |= KeyModifiers::CONTROL;
423     }
424 
425     Ok((kind, modifiers))
426 }
427 
parse_utf8_char(buffer: &[u8]) -> Result<Option<char>>428 pub(crate) fn parse_utf8_char(buffer: &[u8]) -> Result<Option<char>> {
429     match std::str::from_utf8(buffer) {
430         Ok(s) => {
431             let ch = s.chars().next().ok_or_else(could_not_parse_event_error)?;
432 
433             Ok(Some(ch))
434         }
435         Err(_) => {
436             // from_utf8 failed, but we have to check if we need more bytes for code point
437             // and if all the bytes we have no are valid
438 
439             let required_bytes = match buffer[0] {
440                 // https://en.wikipedia.org/wiki/UTF-8#Description
441                 (0x00..=0x7F) => 1, // 0xxxxxxx
442                 (0xC0..=0xDF) => 2, // 110xxxxx 10xxxxxx
443                 (0xE0..=0xEF) => 3, // 1110xxxx 10xxxxxx 10xxxxxx
444                 (0xF0..=0xF7) => 4, // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
445                 (0x80..=0xBF) | (0xF8..=0xFF) => return Err(could_not_parse_event_error()),
446             };
447 
448             // More than 1 byte, check them for 10xxxxxx pattern
449             if required_bytes > 1 && buffer.len() > 1 {
450                 for byte in &buffer[1..] {
451                     if byte & !0b0011_1111 != 0b1000_0000 {
452                         return Err(could_not_parse_event_error());
453                     }
454                 }
455             }
456 
457             if buffer.len() < required_bytes {
458                 // All bytes looks good so far, but we need more of them
459                 Ok(None)
460             } else {
461                 Err(could_not_parse_event_error())
462             }
463         }
464     }
465 }
466 
467 #[cfg(test)]
468 mod tests {
469     use crate::event::{KeyModifiers, MouseButton, MouseEvent};
470 
471     use super::*;
472 
473     #[test]
test_esc_key()474     fn test_esc_key() {
475         assert_eq!(
476             parse_event(b"\x1B", false).unwrap(),
477             Some(InternalEvent::Event(Event::Key(KeyCode::Esc.into()))),
478         );
479     }
480 
481     #[test]
test_possible_esc_sequence()482     fn test_possible_esc_sequence() {
483         assert_eq!(parse_event(b"\x1B", true).unwrap(), None,);
484     }
485 
486     #[test]
test_alt_key()487     fn test_alt_key() {
488         assert_eq!(
489             parse_event(b"\x1Bc", false).unwrap(),
490             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
491                 KeyCode::Char('c'),
492                 KeyModifiers::ALT
493             )))),
494         );
495     }
496 
497     #[test]
test_alt_shift()498     fn test_alt_shift() {
499         assert_eq!(
500             parse_event(b"\x1BH", false).unwrap(),
501             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
502                 KeyCode::Char('H'),
503                 KeyModifiers::ALT | KeyModifiers::SHIFT
504             )))),
505         );
506     }
507 
508     #[test]
test_alt_ctrl()509     fn test_alt_ctrl() {
510         assert_eq!(
511             parse_event(b"\x1B\x14", false).unwrap(),
512             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
513                 KeyCode::Char('t'),
514                 KeyModifiers::ALT | KeyModifiers::CONTROL
515             )))),
516         );
517     }
518 
519     #[test]
test_parse_event_subsequent_calls()520     fn test_parse_event_subsequent_calls() {
521         // The main purpose of this test is to check if we're passing
522         // correct slice to other parse_ functions.
523 
524         // parse_csi_cursor_position
525         assert_eq!(
526             parse_event(b"\x1B[20;10R", false).unwrap(),
527             Some(InternalEvent::CursorPosition(9, 19))
528         );
529 
530         // parse_csi
531         assert_eq!(
532             parse_event(b"\x1B[D", false).unwrap(),
533             Some(InternalEvent::Event(Event::Key(KeyCode::Left.into()))),
534         );
535 
536         // parse_csi_modifier_key_code
537         assert_eq!(
538             parse_event(b"\x1B[2D", false).unwrap(),
539             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
540                 KeyCode::Left,
541                 KeyModifiers::SHIFT
542             ))))
543         );
544 
545         // parse_csi_special_key_code
546         assert_eq!(
547             parse_event(b"\x1B[3~", false).unwrap(),
548             Some(InternalEvent::Event(Event::Key(KeyCode::Delete.into()))),
549         );
550 
551         // parse_csi_rxvt_mouse
552         assert_eq!(
553             parse_event(b"\x1B[32;30;40;M", false).unwrap(),
554             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
555                 kind: MouseEventKind::Down(MouseButton::Left),
556                 column: 29,
557                 row: 39,
558                 modifiers: KeyModifiers::empty(),
559             })))
560         );
561 
562         // parse_csi_normal_mouse
563         assert_eq!(
564             parse_event(b"\x1B[M0\x60\x70", false).unwrap(),
565             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
566                 kind: MouseEventKind::Down(MouseButton::Left),
567                 column: 63,
568                 row: 79,
569                 modifiers: KeyModifiers::CONTROL,
570             })))
571         );
572 
573         // parse_csi_sgr_mouse
574         assert_eq!(
575             parse_event(b"\x1B[<0;20;10;M", false).unwrap(),
576             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
577                 kind: MouseEventKind::Down(MouseButton::Left),
578                 column: 19,
579                 row: 9,
580                 modifiers: KeyModifiers::empty(),
581             })))
582         );
583 
584         // parse_utf8_char
585         assert_eq!(
586             parse_event("Ž".as_bytes(), false).unwrap(),
587             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
588                 KeyCode::Char('Ž'),
589                 KeyModifiers::SHIFT
590             )))),
591         );
592     }
593 
594     #[test]
test_parse_event()595     fn test_parse_event() {
596         assert_eq!(
597             parse_event(b"\t", false).unwrap(),
598             Some(InternalEvent::Event(Event::Key(KeyCode::Tab.into()))),
599         );
600     }
601 
602     #[test]
test_parse_csi_cursor_position()603     fn test_parse_csi_cursor_position() {
604         assert_eq!(
605             parse_csi_cursor_position(b"\x1B[20;10R").unwrap(),
606             Some(InternalEvent::CursorPosition(9, 19))
607         );
608     }
609 
610     #[test]
test_parse_csi()611     fn test_parse_csi() {
612         assert_eq!(
613             parse_csi(b"\x1B[D").unwrap(),
614             Some(InternalEvent::Event(Event::Key(KeyCode::Left.into()))),
615         );
616     }
617 
618     #[test]
test_parse_csi_modifier_key_code()619     fn test_parse_csi_modifier_key_code() {
620         assert_eq!(
621             parse_csi_modifier_key_code(b"\x1B[2D").unwrap(),
622             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
623                 KeyCode::Left,
624                 KeyModifiers::SHIFT
625             )))),
626         );
627     }
628 
629     #[test]
test_parse_csi_special_key_code()630     fn test_parse_csi_special_key_code() {
631         assert_eq!(
632             parse_csi_special_key_code(b"\x1B[3~").unwrap(),
633             Some(InternalEvent::Event(Event::Key(KeyCode::Delete.into()))),
634         );
635     }
636 
637     #[test]
test_parse_csi_special_key_code_multiple_values_not_supported()638     fn test_parse_csi_special_key_code_multiple_values_not_supported() {
639         assert_eq!(
640             parse_csi_special_key_code(b"\x1B[3;2~").unwrap(),
641             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
642                 KeyCode::Delete,
643                 KeyModifiers::SHIFT
644             )))),
645         );
646     }
647 
648     #[test]
test_parse_csi_rxvt_mouse()649     fn test_parse_csi_rxvt_mouse() {
650         assert_eq!(
651             parse_csi_rxvt_mouse(b"\x1B[32;30;40;M").unwrap(),
652             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
653                 kind: MouseEventKind::Down(MouseButton::Left),
654                 column: 29,
655                 row: 39,
656                 modifiers: KeyModifiers::empty(),
657             })))
658         );
659     }
660 
661     #[test]
test_parse_csi_normal_mouse()662     fn test_parse_csi_normal_mouse() {
663         assert_eq!(
664             parse_csi_normal_mouse(b"\x1B[M0\x60\x70").unwrap(),
665             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
666                 kind: MouseEventKind::Down(MouseButton::Left),
667                 column: 63,
668                 row: 79,
669                 modifiers: KeyModifiers::CONTROL,
670             })))
671         );
672     }
673 
674     #[test]
test_parse_csi_sgr_mouse()675     fn test_parse_csi_sgr_mouse() {
676         assert_eq!(
677             parse_csi_sgr_mouse(b"\x1B[<0;20;10;M").unwrap(),
678             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
679                 kind: MouseEventKind::Down(MouseButton::Left),
680                 column: 19,
681                 row: 9,
682                 modifiers: KeyModifiers::empty(),
683             })))
684         );
685         assert_eq!(
686             parse_csi_sgr_mouse(b"\x1B[<0;20;10M").unwrap(),
687             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
688                 kind: MouseEventKind::Down(MouseButton::Left),
689                 column: 19,
690                 row: 9,
691                 modifiers: KeyModifiers::empty(),
692             })))
693         );
694         assert_eq!(
695             parse_csi_sgr_mouse(b"\x1B[<0;20;10;m").unwrap(),
696             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
697                 kind: MouseEventKind::Up(MouseButton::Left),
698                 column: 19,
699                 row: 9,
700                 modifiers: KeyModifiers::empty(),
701             })))
702         );
703         assert_eq!(
704             parse_csi_sgr_mouse(b"\x1B[<0;20;10m").unwrap(),
705             Some(InternalEvent::Event(Event::Mouse(MouseEvent {
706                 kind: MouseEventKind::Up(MouseButton::Left),
707                 column: 19,
708                 row: 9,
709                 modifiers: KeyModifiers::empty(),
710             })))
711         );
712     }
713 
714     #[test]
test_utf8()715     fn test_utf8() {
716         // https://www.php.net/manual/en/reference.pcre.pattern.modifiers.php#54805
717 
718         // 'Valid ASCII' => "a",
719         assert_eq!(parse_utf8_char(b"a").unwrap(), Some('a'),);
720 
721         // 'Valid 2 Octet Sequence' => "\xc3\xb1",
722         assert_eq!(parse_utf8_char(&[0xC3, 0xB1]).unwrap(), Some('ñ'),);
723 
724         // 'Invalid 2 Octet Sequence' => "\xc3\x28",
725         assert!(parse_utf8_char(&[0xC3, 0x28]).is_err());
726 
727         // 'Invalid Sequence Identifier' => "\xa0\xa1",
728         assert!(parse_utf8_char(&[0xA0, 0xA1]).is_err());
729 
730         // 'Valid 3 Octet Sequence' => "\xe2\x82\xa1",
731         assert_eq!(
732             parse_utf8_char(&[0xE2, 0x81, 0xA1]).unwrap(),
733             Some('\u{2061}'),
734         );
735 
736         // 'Invalid 3 Octet Sequence (in 2nd Octet)' => "\xe2\x28\xa1",
737         assert!(parse_utf8_char(&[0xE2, 0x28, 0xA1]).is_err());
738 
739         // 'Invalid 3 Octet Sequence (in 3rd Octet)' => "\xe2\x82\x28",
740         assert!(parse_utf8_char(&[0xE2, 0x82, 0x28]).is_err());
741 
742         // 'Valid 4 Octet Sequence' => "\xf0\x90\x8c\xbc",
743         assert_eq!(
744             parse_utf8_char(&[0xF0, 0x90, 0x8C, 0xBC]).unwrap(),
745             Some('��'),
746         );
747 
748         // 'Invalid 4 Octet Sequence (in 2nd Octet)' => "\xf0\x28\x8c\xbc",
749         assert!(parse_utf8_char(&[0xF0, 0x28, 0x8C, 0xBC]).is_err());
750 
751         // 'Invalid 4 Octet Sequence (in 3rd Octet)' => "\xf0\x90\x28\xbc",
752         assert!(parse_utf8_char(&[0xF0, 0x90, 0x28, 0xBC]).is_err());
753 
754         // 'Invalid 4 Octet Sequence (in 4th Octet)' => "\xf0\x28\x8c\x28",
755         assert!(parse_utf8_char(&[0xF0, 0x28, 0x8C, 0x28]).is_err());
756     }
757 
758     #[test]
test_parse_char_event_lowercase()759     fn test_parse_char_event_lowercase() {
760         assert_eq!(
761             parse_event(b"c", false).unwrap(),
762             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
763                 KeyCode::Char('c'),
764                 KeyModifiers::empty()
765             )))),
766         );
767     }
768 
769     #[test]
test_parse_char_event_uppercase()770     fn test_parse_char_event_uppercase() {
771         assert_eq!(
772             parse_event(b"C", false).unwrap(),
773             Some(InternalEvent::Event(Event::Key(KeyEvent::new(
774                 KeyCode::Char('C'),
775                 KeyModifiers::SHIFT
776             )))),
777         );
778     }
779 }
780