1#![deny(clippy::all, clippy::if_not_else, clippy::enum_glob_use)]
30#![cfg_attr(not(feature = "std"), no_std)]
31
32use core::mem::MaybeUninit;
33use core::str;
34
35#[cfg(not(feature = "std"))]
36use arrayvec::ArrayVec;
37
38mod params;
39
40#[cfg(feature = "ansi")]
41pub mod ansi;
42pub use params::{Params, ParamsIter};
43
44const MAX_INTERMEDIATES: usize = 2;
45const MAX_OSC_PARAMS: usize = 16;
46const MAX_OSC_RAW: usize = 1024;
47
48#[derive(Default)]
55pub struct Parser<const OSC_RAW_BUF_SIZE: usize = MAX_OSC_RAW> {
56 state: State,
57 intermediates: [u8; MAX_INTERMEDIATES],
58 intermediate_idx: usize,
59 params: Params,
60 param: u16,
61 #[cfg(not(feature = "std"))]
62 osc_raw: ArrayVec<u8, OSC_RAW_BUF_SIZE>,
63 #[cfg(feature = "std")]
64 osc_raw: Vec<u8>,
65 osc_params: [(usize, usize); MAX_OSC_PARAMS],
66 osc_num_params: usize,
67 ignoring: bool,
68 partial_utf8: [u8; 4],
69 partial_utf8_len: usize,
70}
71
72impl Parser {
73 pub fn new() -> Parser {
75 Default::default()
76 }
77}
78
79impl<const OSC_RAW_BUF_SIZE: usize> Parser<OSC_RAW_BUF_SIZE> {
80 #[cfg(not(feature = "std"))]
89 pub fn new_with_size() -> Parser<OSC_RAW_BUF_SIZE> {
90 Default::default()
91 }
92
93 #[inline]
94 fn params(&self) -> &Params {
95 &self.params
96 }
97
98 #[inline]
99 fn intermediates(&self) -> &[u8] {
100 &self.intermediates[..self.intermediate_idx]
101 }
102
103 #[inline]
109 pub fn advance<P: Perform>(&mut self, performer: &mut P, bytes: &[u8]) {
110 let mut i = 0;
111
112 if self.partial_utf8_len != 0 {
114 i += self.advance_partial_utf8(performer, bytes);
115 }
116
117 while i != bytes.len() {
118 match self.state {
119 State::Ground => i += self.advance_ground(performer, &bytes[i..]),
120 _ => {
121 let byte = bytes[i];
123 self.change_state(performer, byte);
124 i += 1;
125 },
126 }
127 }
128 }
129
130 #[inline]
139 #[must_use = "Returned value should be used to processs the remaining bytes"]
140 pub fn advance_until_terminated<P: Perform>(
141 &mut self,
142 performer: &mut P,
143 bytes: &[u8],
144 ) -> usize {
145 let mut i = 0;
146
147 if self.partial_utf8_len != 0 {
149 i += self.advance_partial_utf8(performer, bytes);
150 }
151
152 while i != bytes.len() && !performer.terminated() {
153 match self.state {
154 State::Ground => i += self.advance_ground(performer, &bytes[i..]),
155 _ => {
156 let byte = bytes[i];
158 self.change_state(performer, byte);
159 i += 1;
160 },
161 }
162 }
163
164 i
165 }
166
167 #[inline(always)]
168 fn change_state<P: Perform>(&mut self, performer: &mut P, byte: u8) {
169 match self.state {
170 State::CsiEntry => self.advance_csi_entry(performer, byte),
171 State::CsiIgnore => self.advance_csi_ignore(performer, byte),
172 State::CsiIntermediate => self.advance_csi_intermediate(performer, byte),
173 State::CsiParam => self.advance_csi_param(performer, byte),
174 State::DcsEntry => self.advance_dcs_entry(performer, byte),
175 State::DcsIgnore => self.anywhere(performer, byte),
176 State::DcsIntermediate => self.advance_dcs_intermediate(performer, byte),
177 State::DcsParam => self.advance_dcs_param(performer, byte),
178 State::DcsPassthrough => self.advance_dcs_passthrough(performer, byte),
179 State::Escape => self.advance_esc(performer, byte),
180 State::EscapeIntermediate => self.advance_esc_intermediate(performer, byte),
181 State::OscString => self.advance_osc_string(performer, byte),
182 State::SosPmApcString => self.anywhere(performer, byte),
183 State::Ground => unreachable!(),
184 }
185 }
186
187 #[inline(always)]
188 fn advance_csi_entry<P: Perform>(&mut self, performer: &mut P, byte: u8) {
189 match byte {
190 0x00..=0x17 | 0x19 | 0x1C..=0x1F => performer.execute(byte),
191 0x20..=0x2F => {
192 self.action_collect(byte);
193 self.state = State::CsiIntermediate
194 },
195 0x30..=0x39 => {
196 self.action_paramnext(byte);
197 self.state = State::CsiParam
198 },
199 0x3A => {
200 self.action_subparam();
201 self.state = State::CsiParam
202 },
203 0x3B => {
204 self.action_param();
205 self.state = State::CsiParam
206 },
207 0x3C..=0x3F => {
208 self.action_collect(byte);
209 self.state = State::CsiParam
210 },
211 0x40..=0x7E => self.action_csi_dispatch(performer, byte),
212 _ => self.anywhere(performer, byte),
213 }
214 }
215
216 #[inline(always)]
217 fn advance_csi_ignore<P: Perform>(&mut self, performer: &mut P, byte: u8) {
218 match byte {
219 0x00..=0x17 | 0x19 | 0x1C..=0x1F => performer.execute(byte),
220 0x20..=0x3F => (),
221 0x40..=0x7E => self.state = State::Ground,
222 0x7F => (),
223 _ => self.anywhere(performer, byte),
224 }
225 }
226
227 #[inline(always)]
228 fn advance_csi_intermediate<P: Perform>(&mut self, performer: &mut P, byte: u8) {
229 match byte {
230 0x00..=0x17 | 0x19 | 0x1C..=0x1F => performer.execute(byte),
231 0x20..=0x2F => self.action_collect(byte),
232 0x30..=0x3F => self.state = State::CsiIgnore,
233 0x40..=0x7E => self.action_csi_dispatch(performer, byte),
234 _ => self.anywhere(performer, byte),
235 }
236 }
237
238 #[inline(always)]
239 fn advance_csi_param<P: Perform>(&mut self, performer: &mut P, byte: u8) {
240 match byte {
241 0x00..=0x17 | 0x19 | 0x1C..=0x1F => performer.execute(byte),
242 0x20..=0x2F => {
243 self.action_collect(byte);
244 self.state = State::CsiIntermediate
245 },
246 0x30..=0x39 => self.action_paramnext(byte),
247 0x3A => self.action_subparam(),
248 0x3B => self.action_param(),
249 0x3C..=0x3F => self.state = State::CsiIgnore,
250 0x40..=0x7E => self.action_csi_dispatch(performer, byte),
251 0x7F => (),
252 _ => self.anywhere(performer, byte),
253 }
254 }
255
256 #[inline(always)]
257 fn advance_dcs_entry<P: Perform>(&mut self, performer: &mut P, byte: u8) {
258 match byte {
259 0x00..=0x17 | 0x19 | 0x1C..=0x1F => (),
260 0x20..=0x2F => {
261 self.action_collect(byte);
262 self.state = State::DcsIntermediate
263 },
264 0x30..=0x39 => {
265 self.action_paramnext(byte);
266 self.state = State::DcsParam
267 },
268 0x3A => {
269 self.action_subparam();
270 self.state = State::DcsParam
271 },
272 0x3B => {
273 self.action_param();
274 self.state = State::DcsParam
275 },
276 0x3C..=0x3F => {
277 self.action_collect(byte);
278 self.state = State::DcsParam
279 },
280 0x40..=0x7E => self.action_hook(performer, byte),
281 0x7F => (),
282 _ => self.anywhere(performer, byte),
283 }
284 }
285
286 #[inline(always)]
287 fn advance_dcs_intermediate<P: Perform>(&mut self, performer: &mut P, byte: u8) {
288 match byte {
289 0x00..=0x17 | 0x19 | 0x1C..=0x1F => (),
290 0x20..=0x2F => self.action_collect(byte),
291 0x30..=0x3F => self.state = State::DcsIgnore,
292 0x40..=0x7E => self.action_hook(performer, byte),
293 0x7F => (),
294 _ => self.anywhere(performer, byte),
295 }
296 }
297
298 #[inline(always)]
299 fn advance_dcs_param<P: Perform>(&mut self, performer: &mut P, byte: u8) {
300 match byte {
301 0x00..=0x17 | 0x19 | 0x1C..=0x1F => (),
302 0x20..=0x2F => {
303 self.action_collect(byte);
304 self.state = State::DcsIntermediate
305 },
306 0x30..=0x39 => self.action_paramnext(byte),
307 0x3A => self.action_subparam(),
308 0x3B => self.action_param(),
309 0x3C..=0x3F => self.state = State::DcsIgnore,
310 0x40..=0x7E => self.action_hook(performer, byte),
311 0x7F => (),
312 _ => self.anywhere(performer, byte),
313 }
314 }
315
316 #[inline(always)]
317 fn advance_dcs_passthrough<P: Perform>(&mut self, performer: &mut P, byte: u8) {
318 match byte {
319 0x00..=0x17 | 0x19 | 0x1C..=0x7E => performer.put(byte),
320 0x18 | 0x1A => {
321 performer.unhook();
322 performer.execute(byte);
323 self.state = State::Ground
324 },
325 0x1B => {
326 performer.unhook();
327 self.reset_params();
328 self.state = State::Escape
329 },
330 0x7F => (),
331 0x9C => {
332 performer.unhook();
333 self.state = State::Ground
334 },
335 _ => (),
336 }
337 }
338
339 #[inline(always)]
340 fn advance_esc<P: Perform>(&mut self, performer: &mut P, byte: u8) {
341 match byte {
342 0x00..=0x17 | 0x19 | 0x1C..=0x1F => performer.execute(byte),
343 0x20..=0x2F => {
344 self.action_collect(byte);
345 self.state = State::EscapeIntermediate
346 },
347 0x30..=0x4F => {
348 performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
349 self.state = State::Ground
350 },
351 0x50 => {
352 self.reset_params();
353 self.state = State::DcsEntry
354 },
355 0x51..=0x57 => {
356 performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
357 self.state = State::Ground
358 },
359 0x58 => self.state = State::SosPmApcString,
360 0x59..=0x5A => {
361 performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
362 self.state = State::Ground
363 },
364 0x5B => {
365 self.reset_params();
366 self.state = State::CsiEntry
367 },
368 0x5C => {
369 performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
370 self.state = State::Ground
371 },
372 0x5D => {
373 self.osc_raw.clear();
374 self.osc_num_params = 0;
375 self.state = State::OscString
376 },
377 0x5E..=0x5F => self.state = State::SosPmApcString,
378 0x60..=0x7E => {
379 performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
380 self.state = State::Ground
381 },
382 0x18 | 0x1A => {
384 performer.execute(byte);
385 self.state = State::Ground
386 },
387 0x1B => (),
388 _ => (),
389 }
390 }
391
392 #[inline(always)]
393 fn advance_esc_intermediate<P: Perform>(&mut self, performer: &mut P, byte: u8) {
394 match byte {
395 0x00..=0x17 | 0x19 | 0x1C..=0x1F => performer.execute(byte),
396 0x20..=0x2F => self.action_collect(byte),
397 0x30..=0x7E => {
398 performer.esc_dispatch(self.intermediates(), self.ignoring, byte);
399 self.state = State::Ground
400 },
401 0x7F => (),
402 _ => self.anywhere(performer, byte),
403 }
404 }
405
406 #[inline(always)]
407 fn advance_osc_string<P: Perform>(&mut self, performer: &mut P, byte: u8) {
408 match byte {
409 0x00..=0x06 | 0x08..=0x17 | 0x19 | 0x1C..=0x1F => (),
410 0x07 => {
411 self.osc_end(performer, byte);
412 self.state = State::Ground
413 },
414 0x18 | 0x1A => {
415 self.osc_end(performer, byte);
416 performer.execute(byte);
417 self.state = State::Ground
418 },
419 0x1B => {
420 self.osc_end(performer, byte);
421 self.reset_params();
422 self.state = State::Escape
423 },
424 0x3B => {
425 #[cfg(not(feature = "std"))]
426 {
427 if self.osc_raw.is_full() {
428 return;
429 }
430 }
431 self.action_osc_put_param()
432 },
433 _ => self.action_osc_put(byte),
434 }
435 }
436
437 #[inline(always)]
438 fn anywhere<P: Perform>(&mut self, performer: &mut P, byte: u8) {
439 match byte {
440 0x18 | 0x1A => {
441 performer.execute(byte);
442 self.state = State::Ground
443 },
444 0x1B => {
445 self.reset_params();
446 self.state = State::Escape
447 },
448 _ => (),
449 }
450 }
451
452 #[inline]
453 fn action_csi_dispatch<P: Perform>(&mut self, performer: &mut P, byte: u8) {
454 if self.params.is_full() {
455 self.ignoring = true;
456 } else {
457 self.params.push(self.param);
458 }
459 performer.csi_dispatch(self.params(), self.intermediates(), self.ignoring, byte as char);
460
461 self.state = State::Ground
462 }
463
464 #[inline]
465 fn action_hook<P: Perform>(&mut self, performer: &mut P, byte: u8) {
466 if self.params.is_full() {
467 self.ignoring = true;
468 } else {
469 self.params.push(self.param);
470 }
471 performer.hook(self.params(), self.intermediates(), self.ignoring, byte as char);
472 self.state = State::DcsPassthrough;
473 }
474
475 #[inline]
476 fn action_collect(&mut self, byte: u8) {
477 if self.intermediate_idx == MAX_INTERMEDIATES {
478 self.ignoring = true;
479 } else {
480 self.intermediates[self.intermediate_idx] = byte;
481 self.intermediate_idx += 1;
482 }
483 }
484
485 #[inline]
487 fn action_subparam(&mut self) {
488 if self.params.is_full() {
489 self.ignoring = true;
490 } else {
491 self.params.extend(self.param);
492 self.param = 0;
493 }
494 }
495
496 #[inline]
498 fn action_param(&mut self) {
499 if self.params.is_full() {
500 self.ignoring = true;
501 } else {
502 self.params.push(self.param);
503 self.param = 0;
504 }
505 }
506
507 #[inline]
509 fn action_paramnext(&mut self, byte: u8) {
510 if self.params.is_full() {
511 self.ignoring = true;
512 } else {
513 self.param = self.param.saturating_mul(10);
515 self.param = self.param.saturating_add((byte - b'0') as u16);
516 }
517 }
518
519 #[inline]
521 fn action_osc_put_param(&mut self) {
522 let idx = self.osc_raw.len();
523
524 let param_idx = self.osc_num_params;
525 match param_idx {
526 0 => self.osc_params[param_idx] = (0, idx),
528
529 MAX_OSC_PARAMS => return,
531
532 _ => {
534 let prev = self.osc_params[param_idx - 1];
535 let begin = prev.1;
536 self.osc_params[param_idx] = (begin, idx);
537 },
538 }
539
540 self.osc_num_params += 1;
541 }
542
543 #[inline(always)]
544 fn action_osc_put(&mut self, byte: u8) {
545 #[cfg(not(feature = "std"))]
546 {
547 if self.osc_raw.is_full() {
548 return;
549 }
550 }
551 self.osc_raw.push(byte);
552 }
553
554 fn osc_end<P: Perform>(&mut self, performer: &mut P, byte: u8) {
555 self.action_osc_put_param();
556 self.osc_dispatch(performer, byte);
557 self.osc_raw.clear();
558 self.osc_num_params = 0;
559 }
560
561 #[inline]
563 fn reset_params(&mut self) {
564 self.intermediate_idx = 0;
565 self.ignoring = false;
566 self.param = 0;
567
568 self.params.clear();
569 }
570
571 #[inline]
575 fn osc_dispatch<P: Perform>(&self, performer: &mut P, byte: u8) {
576 let mut slices: [MaybeUninit<&[u8]>; MAX_OSC_PARAMS] =
577 unsafe { MaybeUninit::uninit().assume_init() };
578
579 for (i, slice) in slices.iter_mut().enumerate().take(self.osc_num_params) {
580 let indices = self.osc_params[i];
581 *slice = MaybeUninit::new(&self.osc_raw[indices.0..indices.1]);
582 }
583
584 unsafe {
585 let num_params = self.osc_num_params;
586 let params = &slices[..num_params] as *const [MaybeUninit<&[u8]>] as *const [&[u8]];
587 performer.osc_dispatch(&*params, byte == 0x07);
588 }
589 }
590
591 #[inline]
597 fn advance_ground<P: Perform>(&mut self, performer: &mut P, bytes: &[u8]) -> usize {
598 let num_bytes = bytes.len();
600 let plain_chars = memchr::memchr(0x1B, bytes).unwrap_or(num_bytes);
601
602 if plain_chars == 0 {
604 self.state = State::Escape;
605 self.reset_params();
606 return 1;
607 }
608
609 match str::from_utf8(&bytes[..plain_chars]) {
610 Ok(parsed) => {
611 Self::ground_dispatch(performer, parsed);
612 let mut processed = plain_chars;
613
614 if processed < num_bytes {
616 self.state = State::Escape;
617 self.reset_params();
618 processed += 1;
619 }
620
621 processed
622 },
623 Err(err) => {
625 let valid_bytes = err.valid_up_to();
627 let parsed = unsafe { str::from_utf8_unchecked(&bytes[..valid_bytes]) };
628 Self::ground_dispatch(performer, parsed);
629
630 match err.error_len() {
631 Some(len) => {
632 if len == 1 && bytes[valid_bytes] <= 0x9F {
634 performer.execute(bytes[valid_bytes]);
635 } else {
636 performer.print('�');
637 }
638
639 valid_bytes + len
645 },
646 None => {
647 if plain_chars < num_bytes {
648 performer.print('�');
650 self.state = State::Escape;
651 self.reset_params();
652 plain_chars + 1
653 } else {
654 let extra_bytes = num_bytes - valid_bytes;
656 let partial_len = self.partial_utf8_len + extra_bytes;
657 self.partial_utf8[self.partial_utf8_len..partial_len]
658 .copy_from_slice(&bytes[valid_bytes..valid_bytes + extra_bytes]);
659 self.partial_utf8_len = partial_len;
660 num_bytes
661 }
662 },
663 }
664 },
665 }
666 }
667
668 #[inline]
670 fn advance_partial_utf8<P: Perform>(&mut self, performer: &mut P, bytes: &[u8]) -> usize {
671 let old_bytes = self.partial_utf8_len;
673 let to_copy = bytes.len().min(self.partial_utf8.len() - old_bytes);
674 self.partial_utf8[old_bytes..old_bytes + to_copy].copy_from_slice(&bytes[..to_copy]);
675 self.partial_utf8_len += to_copy;
676
677 match str::from_utf8(&self.partial_utf8[..self.partial_utf8_len]) {
679 Ok(parsed) => {
681 let c = unsafe { parsed.chars().next().unwrap_unchecked() };
682 performer.print(c);
683
684 self.partial_utf8_len = 0;
685 c.len_utf8() - old_bytes
686 },
687 Err(err) => {
688 let valid_bytes = err.valid_up_to();
689 if valid_bytes > 0 {
693 let c = unsafe {
694 let parsed = str::from_utf8_unchecked(&self.partial_utf8[..valid_bytes]);
695 parsed.chars().next().unwrap_unchecked()
696 };
697
698 performer.print(c);
699
700 self.partial_utf8_len = 0;
701 return valid_bytes - old_bytes;
702 }
703
704 match err.error_len() {
705 Some(invalid_len) => {
708 performer.print('�');
709
710 self.partial_utf8_len = 0;
711 invalid_len - old_bytes
712 },
713 None => to_copy,
715 }
716 },
717 }
718 }
719
720 #[inline]
722 fn ground_dispatch<P: Perform>(performer: &mut P, text: &str) {
723 for c in text.chars() {
724 match c {
725 '\x00'..='\x1f' | '\u{80}'..='\u{9f}' => performer.execute(c as u8),
726 _ => performer.print(c),
727 }
728 }
729 }
730}
731
732#[derive(PartialEq, Eq, Debug, Default, Copy, Clone)]
733enum State {
734 CsiEntry,
735 CsiIgnore,
736 CsiIntermediate,
737 CsiParam,
738 DcsEntry,
739 DcsIgnore,
740 DcsIntermediate,
741 DcsParam,
742 DcsPassthrough,
743 Escape,
744 EscapeIntermediate,
745 OscString,
746 SosPmApcString,
747 #[default]
748 Ground,
749}
750
751pub trait Perform {
762 fn print(&mut self, _c: char) {}
764
765 fn execute(&mut self, _byte: u8) {}
767
768 fn hook(&mut self, _params: &Params, _intermediates: &[u8], _ignore: bool, _action: char) {}
780
781 fn put(&mut self, _byte: u8) {}
784
785 fn unhook(&mut self) {}
790
791 fn osc_dispatch(&mut self, _params: &[&[u8]], _bell_terminated: bool) {}
793
794 fn csi_dispatch(
800 &mut self,
801 _params: &Params,
802 _intermediates: &[u8],
803 _ignore: bool,
804 _action: char,
805 ) {
806 }
807
808 fn esc_dispatch(&mut self, _intermediates: &[u8], _ignore: bool, _byte: u8) {}
813
814 #[inline(always)]
823 fn terminated(&self) -> bool {
824 false
825 }
826}
827
828#[cfg(all(test, not(feature = "std")))]
829#[macro_use]
830extern crate std;
831
832#[cfg(test)]
833mod tests {
834 use std::vec::Vec;
835
836 use super::*;
837
838 const OSC_BYTES: &[u8] = &[
839 0x1B, 0x5D, b'2', b';', b'j', b'w', b'i', b'l', b'm', b'@', b'j', b'w', b'i', b'l', b'm', b'-', b'd',
841 b'e', b's', b'k', b':', b' ', b'~', b'/', b'c', b'o', b'd', b'e', b'/', b'a', b'l', b'a',
842 b'c', b'r', b'i', b't', b't', b'y', 0x07, ];
844
845 #[derive(Default)]
846 struct Dispatcher {
847 dispatched: Vec<Sequence>,
848 }
849
850 #[derive(Debug, PartialEq, Eq)]
851 enum Sequence {
852 Osc(Vec<Vec<u8>>, bool),
853 Csi(Vec<Vec<u16>>, Vec<u8>, bool, char),
854 Esc(Vec<u8>, bool, u8),
855 DcsHook(Vec<Vec<u16>>, Vec<u8>, bool, char),
856 DcsPut(u8),
857 Print(char),
858 Execute(u8),
859 DcsUnhook,
860 }
861
862 impl Perform for Dispatcher {
863 fn osc_dispatch(&mut self, params: &[&[u8]], bell_terminated: bool) {
864 let params = params.iter().map(|p| p.to_vec()).collect();
865 self.dispatched.push(Sequence::Osc(params, bell_terminated));
866 }
867
868 fn csi_dispatch(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) {
869 let params = params.iter().map(|subparam| subparam.to_vec()).collect();
870 let intermediates = intermediates.to_vec();
871 self.dispatched.push(Sequence::Csi(params, intermediates, ignore, c));
872 }
873
874 fn esc_dispatch(&mut self, intermediates: &[u8], ignore: bool, byte: u8) {
875 let intermediates = intermediates.to_vec();
876 self.dispatched.push(Sequence::Esc(intermediates, ignore, byte));
877 }
878
879 fn hook(&mut self, params: &Params, intermediates: &[u8], ignore: bool, c: char) {
880 let params = params.iter().map(|subparam| subparam.to_vec()).collect();
881 let intermediates = intermediates.to_vec();
882 self.dispatched.push(Sequence::DcsHook(params, intermediates, ignore, c));
883 }
884
885 fn put(&mut self, byte: u8) {
886 self.dispatched.push(Sequence::DcsPut(byte));
887 }
888
889 fn unhook(&mut self) {
890 self.dispatched.push(Sequence::DcsUnhook);
891 }
892
893 fn print(&mut self, c: char) {
894 self.dispatched.push(Sequence::Print(c));
895 }
896
897 fn execute(&mut self, byte: u8) {
898 self.dispatched.push(Sequence::Execute(byte));
899 }
900 }
901
902 #[test]
903 fn parse_osc() {
904 let mut dispatcher = Dispatcher::default();
905 let mut parser = Parser::new();
906
907 parser.advance(&mut dispatcher, OSC_BYTES);
908
909 assert_eq!(dispatcher.dispatched.len(), 1);
910 match &dispatcher.dispatched[0] {
911 Sequence::Osc(params, _) => {
912 assert_eq!(params.len(), 2);
913 assert_eq!(params[0], &OSC_BYTES[2..3]);
914 assert_eq!(params[1], &OSC_BYTES[4..(OSC_BYTES.len() - 1)]);
915 },
916 _ => panic!("expected osc sequence"),
917 }
918 }
919
920 #[test]
921 fn parse_empty_osc() {
922 let mut dispatcher = Dispatcher::default();
923 let mut parser = Parser::new();
924
925 parser.advance(&mut dispatcher, &[0x1B, 0x5D, 0x07]);
926
927 assert_eq!(dispatcher.dispatched.len(), 1);
928 match &dispatcher.dispatched[0] {
929 Sequence::Osc(..) => (),
930 _ => panic!("expected osc sequence"),
931 }
932 }
933
934 #[test]
935 fn parse_osc_max_params() {
936 let params = ";".repeat(params::MAX_PARAMS + 1);
937 let input = format!("\x1b]{}\x1b", ¶ms[..]).into_bytes();
938 let mut dispatcher = Dispatcher::default();
939 let mut parser = Parser::new();
940
941 parser.advance(&mut dispatcher, &input);
942
943 assert_eq!(dispatcher.dispatched.len(), 1);
944 match &dispatcher.dispatched[0] {
945 Sequence::Osc(params, _) => {
946 assert_eq!(params.len(), MAX_OSC_PARAMS);
947 assert!(params.iter().all(Vec::is_empty));
948 },
949 _ => panic!("expected osc sequence"),
950 }
951 }
952
953 #[test]
954 fn osc_bell_terminated() {
955 const INPUT: &[u8] = b"\x1b]11;ff/00/ff\x07";
956 let mut dispatcher = Dispatcher::default();
957 let mut parser = Parser::new();
958
959 parser.advance(&mut dispatcher, INPUT);
960
961 assert_eq!(dispatcher.dispatched.len(), 1);
962 match &dispatcher.dispatched[0] {
963 Sequence::Osc(_, true) => (),
964 _ => panic!("expected osc with bell terminator"),
965 }
966 }
967
968 #[test]
969 fn osc_c0_st_terminated() {
970 const INPUT: &[u8] = b"\x1b]11;ff/00/ff\x1b\\";
971 let mut dispatcher = Dispatcher::default();
972 let mut parser = Parser::new();
973
974 parser.advance(&mut dispatcher, INPUT);
975
976 assert_eq!(dispatcher.dispatched.len(), 2);
977 match &dispatcher.dispatched[0] {
978 Sequence::Osc(_, false) => (),
979 _ => panic!("expected osc with ST terminator"),
980 }
981 }
982
983 #[test]
984 fn parse_osc_with_utf8_arguments() {
985 const INPUT: &[u8] = &[
986 0x0D, 0x1B, 0x5D, 0x32, 0x3B, 0x65, 0x63, 0x68, 0x6F, 0x20, 0x27, 0xC2, 0xAF, 0x5C,
987 0x5F, 0x28, 0xE3, 0x83, 0x84, 0x29, 0x5F, 0x2F, 0xC2, 0xAF, 0x27, 0x20, 0x26, 0x26,
988 0x20, 0x73, 0x6C, 0x65, 0x65, 0x70, 0x20, 0x31, 0x07,
989 ];
990 let mut dispatcher = Dispatcher::default();
991 let mut parser = Parser::new();
992
993 parser.advance(&mut dispatcher, INPUT);
994
995 assert_eq!(dispatcher.dispatched[0], Sequence::Execute(b'\r'));
996 let osc_data = INPUT[5..(INPUT.len() - 1)].into();
997 assert_eq!(dispatcher.dispatched[1], Sequence::Osc(vec![vec![b'2'], osc_data], true));
998 assert_eq!(dispatcher.dispatched.len(), 2);
999 }
1000
1001 #[test]
1002 fn osc_containing_string_terminator() {
1003 const INPUT: &[u8] = b"\x1b]2;\xe6\x9c\xab\x1b\\";
1004 let mut dispatcher = Dispatcher::default();
1005 let mut parser = Parser::new();
1006
1007 parser.advance(&mut dispatcher, INPUT);
1008
1009 assert_eq!(dispatcher.dispatched.len(), 2);
1010 match &dispatcher.dispatched[0] {
1011 Sequence::Osc(params, _) => {
1012 assert_eq!(params[1], &INPUT[4..(INPUT.len() - 2)]);
1013 },
1014 _ => panic!("expected osc sequence"),
1015 }
1016 }
1017
1018 #[test]
1019 fn exceed_max_buffer_size() {
1020 const NUM_BYTES: usize = MAX_OSC_RAW + 100;
1021 const INPUT_START: &[u8] = b"\x1b]52;s";
1022 const INPUT_END: &[u8] = b"\x07";
1023
1024 let mut dispatcher = Dispatcher::default();
1025 let mut parser = Parser::new();
1026
1027 parser.advance(&mut dispatcher, INPUT_START);
1029
1030 parser.advance(&mut dispatcher, &[b'a'; NUM_BYTES]);
1032
1033 parser.advance(&mut dispatcher, INPUT_END);
1035
1036 assert_eq!(dispatcher.dispatched.len(), 1);
1037 match &dispatcher.dispatched[0] {
1038 Sequence::Osc(params, _) => {
1039 assert_eq!(params.len(), 2);
1040 assert_eq!(params[0], b"52");
1041
1042 #[cfg(feature = "std")]
1043 assert_eq!(params[1].len(), NUM_BYTES + INPUT_END.len());
1044
1045 #[cfg(not(feature = "std"))]
1046 assert_eq!(params[1].len(), MAX_OSC_RAW - params[0].len());
1047 },
1048 _ => panic!("expected osc sequence"),
1049 }
1050 }
1051
1052 #[test]
1053 fn parse_csi_max_params() {
1054 let params = "1;".repeat(params::MAX_PARAMS - 1);
1058 let input = format!("\x1b[{}p", ¶ms[..]).into_bytes();
1059
1060 let mut dispatcher = Dispatcher::default();
1061 let mut parser = Parser::new();
1062
1063 parser.advance(&mut dispatcher, &input);
1064
1065 assert_eq!(dispatcher.dispatched.len(), 1);
1066 match &dispatcher.dispatched[0] {
1067 Sequence::Csi(params, _, ignore, _) => {
1068 assert_eq!(params.len(), params::MAX_PARAMS);
1069 assert!(!ignore);
1070 },
1071 _ => panic!("expected csi sequence"),
1072 }
1073 }
1074
1075 #[test]
1076 fn parse_csi_params_ignore_long_params() {
1077 let params = "1;".repeat(params::MAX_PARAMS);
1081 let input = format!("\x1b[{}p", ¶ms[..]).into_bytes();
1082
1083 let mut dispatcher = Dispatcher::default();
1084 let mut parser = Parser::new();
1085
1086 parser.advance(&mut dispatcher, &input);
1087
1088 assert_eq!(dispatcher.dispatched.len(), 1);
1089 match &dispatcher.dispatched[0] {
1090 Sequence::Csi(params, _, ignore, _) => {
1091 assert_eq!(params.len(), params::MAX_PARAMS);
1092 assert!(ignore);
1093 },
1094 _ => panic!("expected csi sequence"),
1095 }
1096 }
1097
1098 #[test]
1099 fn parse_csi_params_trailing_semicolon() {
1100 let mut dispatcher = Dispatcher::default();
1101 let mut parser = Parser::new();
1102
1103 parser.advance(&mut dispatcher, b"\x1b[4;m");
1104
1105 assert_eq!(dispatcher.dispatched.len(), 1);
1106 match &dispatcher.dispatched[0] {
1107 Sequence::Csi(params, ..) => assert_eq!(params, &[[4], [0]]),
1108 _ => panic!("expected csi sequence"),
1109 }
1110 }
1111
1112 #[test]
1113 fn parse_csi_params_leading_semicolon() {
1114 let mut dispatcher = Dispatcher::default();
1116 let mut parser = Parser::new();
1117
1118 parser.advance(&mut dispatcher, b"\x1b[;4m");
1119
1120 assert_eq!(dispatcher.dispatched.len(), 1);
1121 match &dispatcher.dispatched[0] {
1122 Sequence::Csi(params, ..) => assert_eq!(params, &[[0], [4]]),
1123 _ => panic!("expected csi sequence"),
1124 }
1125 }
1126
1127 #[test]
1128 fn parse_long_csi_param() {
1129 const INPUT: &[u8] = b"\x1b[9223372036854775808m";
1131 let mut dispatcher = Dispatcher::default();
1132 let mut parser = Parser::new();
1133
1134 parser.advance(&mut dispatcher, INPUT);
1135
1136 assert_eq!(dispatcher.dispatched.len(), 1);
1137 match &dispatcher.dispatched[0] {
1138 Sequence::Csi(params, ..) => assert_eq!(params, &[[u16::MAX]]),
1139 _ => panic!("expected csi sequence"),
1140 }
1141 }
1142
1143 #[test]
1144 fn csi_reset() {
1145 const INPUT: &[u8] = b"\x1b[3;1\x1b[?1049h";
1146 let mut dispatcher = Dispatcher::default();
1147 let mut parser = Parser::new();
1148
1149 parser.advance(&mut dispatcher, INPUT);
1150
1151 assert_eq!(dispatcher.dispatched.len(), 1);
1152 match &dispatcher.dispatched[0] {
1153 Sequence::Csi(params, intermediates, ignore, _) => {
1154 assert_eq!(intermediates, b"?");
1155 assert_eq!(params, &[[1049]]);
1156 assert!(!ignore);
1157 },
1158 _ => panic!("expected csi sequence"),
1159 }
1160 }
1161
1162 #[test]
1163 fn csi_subparameters() {
1164 const INPUT: &[u8] = b"\x1b[38:2:255:0:255;1m";
1165 let mut dispatcher = Dispatcher::default();
1166 let mut parser = Parser::new();
1167
1168 parser.advance(&mut dispatcher, INPUT);
1169
1170 assert_eq!(dispatcher.dispatched.len(), 1);
1171 match &dispatcher.dispatched[0] {
1172 Sequence::Csi(params, intermediates, ignore, _) => {
1173 assert_eq!(params, &[vec![38, 2, 255, 0, 255], vec![1]]);
1174 assert_eq!(intermediates, &[]);
1175 assert!(!ignore);
1176 },
1177 _ => panic!("expected csi sequence"),
1178 }
1179 }
1180
1181 #[test]
1182 fn parse_dcs_max_params() {
1183 let params = "1;".repeat(params::MAX_PARAMS + 1);
1184 let input = format!("\x1bP{}p", ¶ms[..]).into_bytes();
1185 let mut dispatcher = Dispatcher::default();
1186 let mut parser = Parser::new();
1187
1188 parser.advance(&mut dispatcher, &input);
1189
1190 assert_eq!(dispatcher.dispatched.len(), 1);
1191 match &dispatcher.dispatched[0] {
1192 Sequence::DcsHook(params, _, ignore, _) => {
1193 assert_eq!(params.len(), params::MAX_PARAMS);
1194 assert!(params.iter().all(|param| param == &[1]));
1195 assert!(ignore);
1196 },
1197 _ => panic!("expected dcs sequence"),
1198 }
1199 }
1200
1201 #[test]
1202 fn dcs_reset() {
1203 const INPUT: &[u8] = b"\x1b[3;1\x1bP1$tx\x9c";
1204 let mut dispatcher = Dispatcher::default();
1205 let mut parser = Parser::new();
1206
1207 parser.advance(&mut dispatcher, INPUT);
1208
1209 assert_eq!(dispatcher.dispatched.len(), 3);
1210 match &dispatcher.dispatched[0] {
1211 Sequence::DcsHook(params, intermediates, ignore, _) => {
1212 assert_eq!(intermediates, b"$");
1213 assert_eq!(params, &[[1]]);
1214 assert!(!ignore);
1215 },
1216 _ => panic!("expected dcs sequence"),
1217 }
1218 assert_eq!(dispatcher.dispatched[1], Sequence::DcsPut(b'x'));
1219 assert_eq!(dispatcher.dispatched[2], Sequence::DcsUnhook);
1220 }
1221
1222 #[test]
1223 fn parse_dcs() {
1224 const INPUT: &[u8] = b"\x1bP0;1|17/ab\x9c";
1225 let mut dispatcher = Dispatcher::default();
1226 let mut parser = Parser::new();
1227
1228 parser.advance(&mut dispatcher, INPUT);
1229
1230 assert_eq!(dispatcher.dispatched.len(), 7);
1231 match &dispatcher.dispatched[0] {
1232 Sequence::DcsHook(params, _, _, c) => {
1233 assert_eq!(params, &[[0], [1]]);
1234 assert_eq!(c, &'|');
1235 },
1236 _ => panic!("expected dcs sequence"),
1237 }
1238 for (i, byte) in b"17/ab".iter().enumerate() {
1239 assert_eq!(dispatcher.dispatched[1 + i], Sequence::DcsPut(*byte));
1240 }
1241 assert_eq!(dispatcher.dispatched[6], Sequence::DcsUnhook);
1242 }
1243
1244 #[test]
1245 fn intermediate_reset_on_dcs_exit() {
1246 const INPUT: &[u8] = b"\x1bP=1sZZZ\x1b+\x5c";
1247 let mut dispatcher = Dispatcher::default();
1248 let mut parser = Parser::new();
1249
1250 parser.advance(&mut dispatcher, INPUT);
1251
1252 assert_eq!(dispatcher.dispatched.len(), 6);
1253 match &dispatcher.dispatched[5] {
1254 Sequence::Esc(intermediates, ..) => assert_eq!(intermediates, b"+"),
1255 _ => panic!("expected esc sequence"),
1256 }
1257 }
1258
1259 #[test]
1260 fn esc_reset() {
1261 const INPUT: &[u8] = b"\x1b[3;1\x1b(A";
1262 let mut dispatcher = Dispatcher::default();
1263 let mut parser = Parser::new();
1264
1265 parser.advance(&mut dispatcher, INPUT);
1266
1267 assert_eq!(dispatcher.dispatched.len(), 1);
1268 match &dispatcher.dispatched[0] {
1269 Sequence::Esc(intermediates, ignore, byte) => {
1270 assert_eq!(intermediates, b"(");
1271 assert_eq!(*byte, b'A');
1272 assert!(!ignore);
1273 },
1274 _ => panic!("expected esc sequence"),
1275 }
1276 }
1277
1278 #[test]
1279 fn esc_reset_intermediates() {
1280 const INPUT: &[u8] = b"\x1b[?2004l\x1b#8";
1281 let mut dispatcher = Dispatcher::default();
1282 let mut parser = Parser::new();
1283
1284 parser.advance(&mut dispatcher, INPUT);
1285
1286 assert_eq!(dispatcher.dispatched.len(), 2);
1287 assert_eq!(dispatcher.dispatched[0], Sequence::Csi(vec![vec![2004]], vec![63], false, 'l'));
1288 assert_eq!(dispatcher.dispatched[1], Sequence::Esc(vec![35], false, 56));
1289 }
1290
1291 #[test]
1292 fn params_buffer_filled_with_subparam() {
1293 const INPUT: &[u8] = b"\x1b[::::::::::::::::::::::::::::::::x\x1b";
1294 let mut dispatcher = Dispatcher::default();
1295 let mut parser = Parser::new();
1296
1297 parser.advance(&mut dispatcher, INPUT);
1298
1299 assert_eq!(dispatcher.dispatched.len(), 1);
1300 match &dispatcher.dispatched[0] {
1301 Sequence::Csi(params, intermediates, ignore, c) => {
1302 assert_eq!(intermediates, &[]);
1303 assert_eq!(params, &[[0; 32]]);
1304 assert_eq!(c, &'x');
1305 assert!(ignore);
1306 },
1307 _ => panic!("expected csi sequence"),
1308 }
1309 }
1310
1311 #[cfg(not(feature = "std"))]
1312 #[test]
1313 fn build_with_fixed_size() {
1314 const INPUT: &[u8] = b"\x1b[3;1\x1b[?1049h";
1315 let mut dispatcher = Dispatcher::default();
1316 let mut parser: Parser<30> = Parser::new_with_size();
1317
1318 parser.advance(&mut dispatcher, INPUT);
1319
1320 assert_eq!(dispatcher.dispatched.len(), 1);
1321 match &dispatcher.dispatched[0] {
1322 Sequence::Csi(params, intermediates, ignore, _) => {
1323 assert_eq!(intermediates, b"?");
1324 assert_eq!(params, &[[1049]]);
1325 assert!(!ignore);
1326 },
1327 _ => panic!("expected csi sequence"),
1328 }
1329 }
1330
1331 #[cfg(not(feature = "std"))]
1332 #[test]
1333 fn exceed_fixed_osc_buffer_size() {
1334 const OSC_BUFFER_SIZE: usize = 32;
1335 const NUM_BYTES: usize = OSC_BUFFER_SIZE + 100;
1336 const INPUT_START: &[u8] = b"\x1b]52;";
1337 const INPUT_END: &[u8] = b"\x07";
1338
1339 let mut dispatcher = Dispatcher::default();
1340 let mut parser: Parser<OSC_BUFFER_SIZE> = Parser::new_with_size();
1341
1342 parser.advance(&mut dispatcher, INPUT_START);
1344
1345 parser.advance(&mut dispatcher, &[b'a'; NUM_BYTES]);
1347
1348 parser.advance(&mut dispatcher, INPUT_END);
1350
1351 assert_eq!(dispatcher.dispatched.len(), 1);
1352 match &dispatcher.dispatched[0] {
1353 Sequence::Osc(params, _) => {
1354 assert_eq!(params.len(), 2);
1355 assert_eq!(params[0], b"52");
1356 assert_eq!(params[1].len(), OSC_BUFFER_SIZE - params[0].len());
1357 for item in params[1].iter() {
1358 assert_eq!(*item, b'a');
1359 }
1360 },
1361 _ => panic!("expected osc sequence"),
1362 }
1363 }
1364
1365 #[cfg(not(feature = "std"))]
1366 #[test]
1367 fn fixed_size_osc_containing_string_terminator() {
1368 const INPUT_START: &[u8] = b"\x1b]2;";
1369 const INPUT_MIDDLE: &[u8] = b"s\xe6\x9c\xab";
1370 const INPUT_END: &[u8] = b"\x1b\\";
1371
1372 let mut dispatcher = Dispatcher::default();
1373 let mut parser: Parser<5> = Parser::new_with_size();
1374
1375 parser.advance(&mut dispatcher, INPUT_START);
1376 parser.advance(&mut dispatcher, INPUT_MIDDLE);
1377 parser.advance(&mut dispatcher, INPUT_END);
1378
1379 assert_eq!(dispatcher.dispatched.len(), 2);
1380 match &dispatcher.dispatched[0] {
1381 Sequence::Osc(params, false) => {
1382 assert_eq!(params[0], b"2");
1383 assert_eq!(params[1], INPUT_MIDDLE);
1384 },
1385 _ => panic!("expected osc sequence"),
1386 }
1387 }
1388
1389 #[test]
1390 fn unicode() {
1391 const INPUT: &[u8] = b"\xF0\x9F\x8E\x89_\xF0\x9F\xA6\x80\xF0\x9F\xA6\x80_\xF0\x9F\x8E\x89";
1392
1393 let mut dispatcher = Dispatcher::default();
1394 let mut parser = Parser::new();
1395
1396 parser.advance(&mut dispatcher, INPUT);
1397
1398 assert_eq!(dispatcher.dispatched.len(), 6);
1399 assert_eq!(dispatcher.dispatched[0], Sequence::Print('🎉'));
1400 assert_eq!(dispatcher.dispatched[1], Sequence::Print('_'));
1401 assert_eq!(dispatcher.dispatched[2], Sequence::Print('🦀'));
1402 assert_eq!(dispatcher.dispatched[3], Sequence::Print('🦀'));
1403 assert_eq!(dispatcher.dispatched[4], Sequence::Print('_'));
1404 assert_eq!(dispatcher.dispatched[5], Sequence::Print('🎉'));
1405 }
1406
1407 #[test]
1408 fn invalid_utf8() {
1409 const INPUT: &[u8] = b"a\xEF\xBCb";
1410
1411 let mut dispatcher = Dispatcher::default();
1412 let mut parser = Parser::new();
1413
1414 parser.advance(&mut dispatcher, INPUT);
1415
1416 assert_eq!(dispatcher.dispatched.len(), 3);
1417 assert_eq!(dispatcher.dispatched[0], Sequence::Print('a'));
1418 assert_eq!(dispatcher.dispatched[1], Sequence::Print('�'));
1419 assert_eq!(dispatcher.dispatched[2], Sequence::Print('b'));
1420 }
1421
1422 #[test]
1423 fn partial_utf8() {
1424 const INPUT: &[u8] = b"\xF0\x9F\x9A\x80";
1425
1426 let mut dispatcher = Dispatcher::default();
1427 let mut parser = Parser::new();
1428
1429 parser.advance(&mut dispatcher, &INPUT[..1]);
1430 parser.advance(&mut dispatcher, &INPUT[1..2]);
1431 parser.advance(&mut dispatcher, &INPUT[2..3]);
1432 parser.advance(&mut dispatcher, &INPUT[3..]);
1433
1434 assert_eq!(dispatcher.dispatched.len(), 1);
1435 assert_eq!(dispatcher.dispatched[0], Sequence::Print('🚀'));
1436 }
1437
1438 #[test]
1439 fn partial_utf8_separating_utf8() {
1440 const INPUT: &[u8] = b"\xC4\xB8\xF0\x9F\x8E\x89";
1446
1447 let mut dispatcher = Dispatcher::default();
1448 let mut parser = Parser::new();
1449
1450 parser.advance(&mut dispatcher, &INPUT[..1]);
1451 parser.advance(&mut dispatcher, &INPUT[1..]);
1452
1453 assert_eq!(dispatcher.dispatched.len(), 2);
1454 assert_eq!(dispatcher.dispatched[0], Sequence::Print('ĸ'));
1455 assert_eq!(dispatcher.dispatched[1], Sequence::Print('🎉'));
1456 }
1457
1458 #[test]
1459 fn partial_invalid_utf8() {
1460 const INPUT: &[u8] = b"a\xEF\xBCb";
1461
1462 let mut dispatcher = Dispatcher::default();
1463 let mut parser = Parser::new();
1464
1465 parser.advance(&mut dispatcher, &INPUT[..1]);
1466 parser.advance(&mut dispatcher, &INPUT[1..2]);
1467 parser.advance(&mut dispatcher, &INPUT[2..3]);
1468 parser.advance(&mut dispatcher, &INPUT[3..]);
1469
1470 assert_eq!(dispatcher.dispatched.len(), 3);
1471 assert_eq!(dispatcher.dispatched[0], Sequence::Print('a'));
1472 assert_eq!(dispatcher.dispatched[1], Sequence::Print('�'));
1473 assert_eq!(dispatcher.dispatched[2], Sequence::Print('b'));
1474 }
1475
1476 #[test]
1477 fn partial_invalid_utf8_split() {
1478 const INPUT: &[u8] = b"\xE4\xBF\x99\xB5";
1479
1480 let mut dispatcher = Dispatcher::default();
1481 let mut parser = Parser::new();
1482
1483 parser.advance(&mut dispatcher, &INPUT[..2]);
1484 parser.advance(&mut dispatcher, &INPUT[2..]);
1485
1486 assert_eq!(dispatcher.dispatched[0], Sequence::Print('ä¿™'));
1487 assert_eq!(dispatcher.dispatched[1], Sequence::Print('�'));
1488 }
1489
1490 #[test]
1491 fn partial_utf8_into_esc() {
1492 const INPUT: &[u8] = b"\xD8\x1b012";
1493
1494 let mut dispatcher = Dispatcher::default();
1495 let mut parser = Parser::new();
1496
1497 parser.advance(&mut dispatcher, INPUT);
1498
1499 assert_eq!(dispatcher.dispatched.len(), 4);
1500 assert_eq!(dispatcher.dispatched[0], Sequence::Print('�'));
1501 assert_eq!(dispatcher.dispatched[1], Sequence::Esc(Vec::new(), false, b'0'));
1502 assert_eq!(dispatcher.dispatched[2], Sequence::Print('1'));
1503 assert_eq!(dispatcher.dispatched[3], Sequence::Print('2'));
1504 }
1505
1506 #[test]
1507 fn c1s() {
1508 const INPUT: &[u8] = b"\x00\x1f\x80\x90\x98\x9b\x9c\x9d\x9e\x9fa";
1509
1510 let mut dispatcher = Dispatcher::default();
1511 let mut parser = Parser::new();
1512
1513 parser.advance(&mut dispatcher, INPUT);
1514
1515 assert_eq!(dispatcher.dispatched.len(), 11);
1516 assert_eq!(dispatcher.dispatched[0], Sequence::Execute(0));
1517 assert_eq!(dispatcher.dispatched[1], Sequence::Execute(31));
1518 assert_eq!(dispatcher.dispatched[2], Sequence::Execute(128));
1519 assert_eq!(dispatcher.dispatched[3], Sequence::Execute(144));
1520 assert_eq!(dispatcher.dispatched[4], Sequence::Execute(152));
1521 assert_eq!(dispatcher.dispatched[5], Sequence::Execute(155));
1522 assert_eq!(dispatcher.dispatched[6], Sequence::Execute(156));
1523 assert_eq!(dispatcher.dispatched[7], Sequence::Execute(157));
1524 assert_eq!(dispatcher.dispatched[8], Sequence::Execute(158));
1525 assert_eq!(dispatcher.dispatched[9], Sequence::Execute(159));
1526 assert_eq!(dispatcher.dispatched[10], Sequence::Print('a'));
1527 }
1528
1529 #[test]
1530 fn execute_anywhere() {
1531 const INPUT: &[u8] = b"\x18\x1a";
1532
1533 let mut dispatcher = Dispatcher::default();
1534 let mut parser = Parser::new();
1535
1536 parser.advance(&mut dispatcher, INPUT);
1537
1538 assert_eq!(dispatcher.dispatched.len(), 2);
1539 assert_eq!(dispatcher.dispatched[0], Sequence::Execute(0x18));
1540 assert_eq!(dispatcher.dispatched[1], Sequence::Execute(0x1A));
1541 }
1542}