1use std::io::{Error, ErrorKind};
4use std::str;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
8pub enum Event {
9 Key(Key),
11 Mouse(MouseEvent),
13 Unsupported(Vec<u8>),
15}
16
17#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
19pub enum MouseEvent {
20 Press(MouseButton, u16, u16),
24 Release(u16, u16),
28 Hold(u16, u16),
32}
33
34#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
36pub enum MouseButton {
37 Left,
39 Right,
41 Middle,
43 WheelUp,
47 WheelDown,
51}
52
53#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
55pub enum Key {
56 Backspace,
58 Left,
60 Right,
62 Up,
64 Down,
66 Home,
68 End,
70 PageUp,
72 PageDown,
74 Delete,
76 Insert,
78 F(u8),
82 Char(char),
84 Alt(char),
86 Ctrl(char),
90 Null,
92 Esc,
94
95 #[doc(hidden)]
96 __IsNotComplete,
97}
98
99pub fn parse_event<I>(item: u8, iter: &mut I) -> Result<Event, Error>
101 where I: Iterator<Item = Result<u8, Error>>
102{
103 let error = Error::new(ErrorKind::Other, "Could not parse an event");
104 match item {
105 b'\x1B' => {
106 Ok(match iter.next() {
108 Some(Ok(b'O')) => {
109 match iter.next() {
110 Some(Ok(val @ b'P'...b'S')) => Event::Key(Key::F(1 + val - b'P')),
112 _ => return Err(error),
113 }
114 }
115 Some(Ok(b'[')) => {
116 parse_csi(iter).ok_or(error)?
118 }
119 Some(Ok(c)) => {
120 let ch = parse_utf8_char(c, iter);
121 Event::Key(Key::Alt(try!(ch)))
122 }
123 Some(Err(_)) | None => return Err(error),
124 })
125 }
126 b'\n' | b'\r' => Ok(Event::Key(Key::Char('\n'))),
127 b'\t' => Ok(Event::Key(Key::Char('\t'))),
128 b'\x7F' => Ok(Event::Key(Key::Backspace)),
129 c @ b'\x01'...b'\x1A' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1 + b'a') as char))),
130 c @ b'\x1C'...b'\x1F' => Ok(Event::Key(Key::Ctrl((c as u8 - 0x1C + b'4') as char))),
131 b'\0' => Ok(Event::Key(Key::Null)),
132 c => {
133 Ok({
134 let ch = parse_utf8_char(c, iter);
135 Event::Key(Key::Char(try!(ch)))
136 })
137 }
138 }
139}
140
141fn parse_csi<I>(iter: &mut I) -> Option<Event>
145 where I: Iterator<Item = Result<u8, Error>>
146{
147 Some(match iter.next() {
148 Some(Ok(b'[')) => match iter.next() {
149 Some(Ok(val @ b'A'...b'E')) => Event::Key(Key::F(1 + val - b'A')),
150 _ => return None,
151 },
152 Some(Ok(b'D')) => Event::Key(Key::Left),
153 Some(Ok(b'C')) => Event::Key(Key::Right),
154 Some(Ok(b'A')) => Event::Key(Key::Up),
155 Some(Ok(b'B')) => Event::Key(Key::Down),
156 Some(Ok(b'H')) => Event::Key(Key::Home),
157 Some(Ok(b'F')) => Event::Key(Key::End),
158 Some(Ok(b'M')) => {
159 let mut next = || iter.next().unwrap().unwrap();
161
162 let cb = next() as i8 - 32;
163 let cx = next().saturating_sub(32) as u16;
165 let cy = next().saturating_sub(32) as u16;
166 Event::Mouse(match cb & 0b11 {
167 0 => {
168 if cb & 0x40 != 0 {
169 MouseEvent::Press(MouseButton::WheelUp, cx, cy)
170 } else {
171 MouseEvent::Press(MouseButton::Left, cx, cy)
172 }
173 }
174 1 => {
175 if cb & 0x40 != 0 {
176 MouseEvent::Press(MouseButton::WheelDown, cx, cy)
177 } else {
178 MouseEvent::Press(MouseButton::Middle, cx, cy)
179 }
180 }
181 2 => MouseEvent::Press(MouseButton::Right, cx, cy),
182 3 => MouseEvent::Release(cx, cy),
183 _ => return None,
184 })
185 }
186 Some(Ok(b'<')) => {
187 let mut buf = Vec::new();
190 let mut c = iter.next().unwrap().unwrap();
191 while match c {
192 b'm' | b'M' => false,
193 _ => true,
194 } {
195 buf.push(c);
196 c = iter.next().unwrap().unwrap();
197 }
198 let str_buf = String::from_utf8(buf).unwrap();
199 let nums = &mut str_buf.split(';');
200
201 let cb = nums.next()
202 .unwrap()
203 .parse::<u16>()
204 .unwrap();
205 let cx = nums.next()
206 .unwrap()
207 .parse::<u16>()
208 .unwrap();
209 let cy = nums.next()
210 .unwrap()
211 .parse::<u16>()
212 .unwrap();
213
214 let event = match cb {
215 0...2 | 64...65 => {
216 let button = match cb {
217 0 => MouseButton::Left,
218 1 => MouseButton::Middle,
219 2 => MouseButton::Right,
220 64 => MouseButton::WheelUp,
221 65 => MouseButton::WheelDown,
222 _ => unreachable!(),
223 };
224 match c {
225 b'M' => MouseEvent::Press(button, cx, cy),
226 b'm' => MouseEvent::Release(cx, cy),
227 _ => return None,
228 }
229 }
230 32 => MouseEvent::Hold(cx, cy),
231 3 => MouseEvent::Release(cx, cy),
232 _ => return None,
233 };
234
235 Event::Mouse(event)
236 }
237 Some(Ok(c @ b'0'...b'9')) => {
238 let mut buf = Vec::new();
240 buf.push(c);
241 let mut c = iter.next().unwrap().unwrap();
242 while c < 64 || c > 126 {
245 buf.push(c);
246 c = iter.next().unwrap().unwrap();
247 }
248
249 match c {
250 b'M' => {
253 let str_buf = String::from_utf8(buf).unwrap();
254
255 let nums: Vec<u16> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
256
257 let cb = nums[0];
258 let cx = nums[1];
259 let cy = nums[2];
260
261 let event = match cb {
262 32 => MouseEvent::Press(MouseButton::Left, cx, cy),
263 33 => MouseEvent::Press(MouseButton::Middle, cx, cy),
264 34 => MouseEvent::Press(MouseButton::Right, cx, cy),
265 35 => MouseEvent::Release(cx, cy),
266 64 => MouseEvent::Hold(cx, cy),
267 96 | 97 => MouseEvent::Press(MouseButton::WheelUp, cx, cy),
268 _ => return None,
269 };
270
271 Event::Mouse(event)
272 }
273 b'~' => {
275 let str_buf = String::from_utf8(buf).unwrap();
276
277 let nums: Vec<u8> = str_buf.split(';').map(|n| n.parse().unwrap()).collect();
280
281 if nums.is_empty() {
282 return None;
283 }
284
285 if nums.len() > 1 {
288 return None;
289 }
290
291 match nums[0] {
292 1 | 7 => Event::Key(Key::Home),
293 2 => Event::Key(Key::Insert),
294 3 => Event::Key(Key::Delete),
295 4 | 8 => Event::Key(Key::End),
296 5 => Event::Key(Key::PageUp),
297 6 => Event::Key(Key::PageDown),
298 v @ 11...15 => Event::Key(Key::F(v - 10)),
299 v @ 17...21 => Event::Key(Key::F(v - 11)),
300 v @ 23...24 => Event::Key(Key::F(v - 12)),
301 _ => return None,
302 }
303 }
304 _ => return None,
305 }
306 }
307 _ => return None,
308 })
309
310}
311
312fn parse_utf8_char<I>(c: u8, iter: &mut I) -> Result<char, Error>
314 where I: Iterator<Item = Result<u8, Error>>
315{
316 let error = Err(Error::new(ErrorKind::Other, "Input character is not valid UTF-8"));
317 if c.is_ascii() {
318 Ok(c as char)
319 } else {
320 let bytes = &mut Vec::new();
321 bytes.push(c);
322
323 loop {
324 match iter.next() {
325 Some(Ok(next)) => {
326 bytes.push(next);
327 if let Ok(st) = str::from_utf8(bytes) {
328 return Ok(st.chars().next().unwrap());
329 }
330 if bytes.len() >= 4 {
331 return error;
332 }
333 }
334 _ => return error,
335 }
336 }
337 }
338}
339
340#[cfg(test)]
341#[test]
342fn test_parse_utf8() {
343 let st = "abcéŷ¤£€ù%323";
344 let ref mut bytes = st.bytes().map(|x| Ok(x));
345 let chars = st.chars();
346 for c in chars {
347 let b = bytes.next().unwrap().unwrap();
348 assert!(c == parse_utf8_char(b, bytes).unwrap());
349 }
350}