1use std::iter::Map;
3
4use smallvec::SmallVec;
5
6use crate::AsciiControl;
7
8fn fmt_utf8_bytes_with_ascii_control(
10 f: &mut std::fmt::Formatter<'_>,
11 bytes: &[u8],
12) -> std::fmt::Result {
13 for chunk in bytes.utf8_chunks() {
14 for c in chunk.valid().chars() {
15 if let Ok(c) = AsciiControl::try_from(c) {
16 write!(f, "{c}")?;
17 } else {
18 write!(f, "{c}")?;
19 }
20 }
21 if !chunk.invalid().is_empty() {
22 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
23 }
24 }
25 Ok(())
26}
27
28fn fmt_utf8_bytes_simple(f: &mut std::fmt::Formatter<'_>, bytes: &[u8]) -> std::fmt::Result {
30 for chunk in bytes.utf8_chunks() {
31 write!(f, "{}", chunk.valid())?;
32 if !chunk.invalid().is_empty() {
33 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
34 }
35 }
36 Ok(())
37}
38
39#[cfg_attr(feature = "serde", derive(serde::Serialize))]
40#[derive(Default, Clone, Copy, PartialEq, Eq)]
41pub struct VTIntermediate {
42 pub(crate) data: [u8; 2],
43}
44
45impl VTIntermediate {
46 pub const fn empty() -> Self {
47 Self { data: [0, 0] }
48 }
49
50 pub const fn one(c: u8) -> Self {
51 assert!(c >= 0x20 && c <= 0x2F);
52 Self { data: [c, 0] }
53 }
54
55 pub const fn two(c1: u8, c2: u8) -> Self {
56 assert!(c1 >= 0x20 && c1 <= 0x2F);
57 assert!(c2 >= 0x20 && c2 <= 0x2F);
58 Self { data: [c1, c2] }
59 }
60
61 pub fn has(&self, c: u8) -> bool {
62 self.data[0] == c || self.data[1] == c
63 }
64
65 pub fn clear(&mut self) {
66 self.data[0] = 0;
67 self.data[1] = 0;
68 }
69
70 pub fn is_empty(&self) -> bool {
71 self.data[0] == 0 && self.data[1] == 0
72 }
73
74 pub fn len(&self) -> usize {
75 self.data.iter().filter(|&&c| c != 0).count()
76 }
77
78 pub fn first(&self) -> Option<u8> {
79 if self.data[0] != 0 {
80 Some(self.data[0])
81 } else {
82 None
83 }
84 }
85
86 pub fn second(&self) -> Option<u8> {
87 if self.data[1] != 0 {
88 Some(self.data[1])
89 } else {
90 None
91 }
92 }
93
94 #[must_use]
95 pub fn push(&mut self, c: u8) -> bool {
96 if !(0x20..=0x2F).contains(&c) {
97 return false;
98 }
99
100 if self.data[0] == c {
102 return false;
103 }
104
105 if self.data[0] == 0 {
106 self.data[0] = c;
107 true
108 } else if self.data[1] == 0 {
109 self.data[1] = c;
110 true
111 } else {
112 false
113 }
114 }
115
116 pub const fn const_eq(&self, other: &Self) -> bool {
117 self.data[0] == other.data[0] && self.data[1] == other.data[1]
118 }
119
120 pub fn byte_len(&self) -> usize {
121 self.data.iter().filter(|&&c| c != 0).count()
122 }
123}
124
125impl std::fmt::Debug for VTIntermediate {
126 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127 write!(f, "'")?;
129 for c in self.data.iter() {
130 if *c == 0 {
131 break;
132 }
133 write!(f, "{}", *c as char)?;
134 }
135 write!(f, "'")?;
136 Ok(())
137 }
138}
139
140pub(crate) type Param = SmallVec<[u8; 32]>;
141pub(crate) type Params = SmallVec<[Param; 8]>;
142
143static EMPTY_PARAMS: Params = Params::new_const();
144
145#[cfg_attr(feature = "serde", derive(serde::Serialize))]
146#[derive(Debug, Copy, Clone, PartialEq, Eq)]
147#[repr(transparent)]
148pub struct ParamBuf<'a> {
149 pub(crate) params: &'a Params,
150}
151
152impl<'a> IntoIterator for ParamBuf<'a> {
153 type Item = &'a [u8];
154 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
155 fn into_iter(self) -> Self::IntoIter {
156 self.params.iter().map(|p| p.as_slice())
157 }
158}
159
160impl<'a> IntoIterator for &ParamBuf<'a> {
161 type Item = &'a [u8];
162 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
163 fn into_iter(self) -> Self::IntoIter {
164 self.params.iter().map(|p| p.as_slice())
165 }
166}
167
168impl<'a> ParamBuf<'a> {
169 pub const fn empty() -> Self {
170 ParamBuf {
171 params: &EMPTY_PARAMS,
172 }
173 }
174
175 pub fn len(&self) -> usize {
176 self.params.len()
177 }
178
179 pub fn is_empty(&self) -> bool {
180 self.params.is_empty()
181 }
182
183 pub fn get(&self, index: usize) -> Option<&[u8]> {
184 self.params.get(index).map(|p| p.as_slice())
185 }
186
187 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
188 self.params.get(index).and_then(|p| {
189 std::str::from_utf8(p.as_slice())
190 .ok()
191 .and_then(|s| s.parse::<T>().ok())
192 })
193 }
194
195 pub fn to_owned(&self) -> ParamBufOwned {
196 ParamBufOwned {
197 params: self.params.iter().cloned().collect(),
198 }
199 }
200
201 pub fn byte_len(&self) -> usize {
202 self.params.iter().map(|p| p.len()).sum::<usize>() + self.params.len().saturating_sub(1)
203 }
204
205 pub fn numeric(&self) -> NumericParamBuf<'a> {
206 NumericParamBuf {
207 params: self.params,
208 }
209 }
210}
211
212#[derive(Debug, Copy, Clone, Default)]
214pub struct NumericParam<'a> {
215 pub(crate) param: &'a [u8],
216}
217
218impl<'a> NumericParam<'a> {
219 pub fn sole(&self) -> Option<u16> {
221 if !self.param.is_empty() && !self.param.contains(&b':') {
222 if let Ok(s) = std::str::from_utf8(self.param) {
223 s.parse::<u16>().ok()
224 } else {
225 None
226 }
227 } else {
228 None
229 }
230 }
231
232 pub fn first(&self) -> Option<u16> {
234 self.into_iter().next().flatten()
235 }
236
237 pub fn is_empty(&self) -> bool {
238 self.param.is_empty()
239 }
240
241 pub fn len(&self) -> usize {
242 self.param.iter().filter(|p| **p == b':').count() + 1
243 }
244
245 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
252 let len = self.len();
253 if buf.len() < len {
254 return Err(buf.len());
255 }
256 for (i, param) in self.into_iter().enumerate() {
257 buf[i] = param.unwrap_or(0);
258 }
259 Ok(&buf[..len])
260 }
261}
262
263impl<'a> IntoIterator for NumericParam<'a> {
264 type Item = Option<u16>;
265 type IntoIter = Map<std::slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> Option<u16>>;
266 fn into_iter(self) -> Self::IntoIter {
267 let fn1: fn(&u8) -> bool = |c: &u8| *c == b':';
268 self.param.split(fn1).map(|p| {
269 if p.is_empty() {
270 None
271 } else {
272 std::str::from_utf8(p)
273 .ok()
274 .and_then(|s| s.parse::<u16>().ok())
275 }
276 })
277 }
278}
279
280#[derive(Debug, Copy, Clone)]
285pub struct NumericParamBuf<'a> {
286 pub(crate) params: &'a Params,
287}
288
289impl<'a> IntoIterator for NumericParamBuf<'a> {
290 type Item = NumericParam<'a>;
291 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&'a Param) -> NumericParam<'a>>;
292 fn into_iter(self) -> Self::IntoIter {
293 self.params.iter().map(|p| NumericParam {
294 param: p.as_slice(),
295 })
296 }
297}
298
299impl<'a> NumericParamBuf<'a> {
300 pub const fn empty() -> Self {
301 NumericParamBuf {
302 params: &EMPTY_PARAMS,
303 }
304 }
305
306 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
313 let len = self.params.len();
314 if buf.len() < len {
315 return Err(buf.len());
316 }
317 for (i, param) in self.into_iter().enumerate() {
318 buf[i] = param.sole().unwrap_or(0);
319 }
320 Ok(&buf[..len])
321 }
322
323 pub fn get(&self, index: usize) -> Option<NumericParam<'a>> {
324 self.params.get(index).map(|p| NumericParam {
325 param: p.as_slice(),
326 })
327 }
328
329 pub fn first(&self) -> Option<NumericParam<'a>> {
330 self.into_iter().next()
331 }
332
333 pub fn is_empty(&self) -> bool {
334 self.params.is_empty()
335 }
336
337 pub fn len(&self) -> usize {
338 self.params.len()
339 }
340}
341
342#[cfg_attr(feature = "serde", derive(serde::Serialize))]
345#[derive(Clone, PartialEq, Eq)]
346pub enum VTEvent<'a> {
347 Raw(&'a [u8]),
349
350 C0(u8),
352
353 Esc(Esc),
355
356 EscInvalid(EscInvalid),
358
359 Ss2(SS2),
361
362 Ss3(SS3),
364
365 Csi(CSI<'a>),
367
368 DcsStart(DCS<'a>),
370 DcsData(&'a [u8]),
371 DcsEnd(&'a [u8]),
372 DcsCancel,
373
374 OscStart,
376 OscData(&'a [u8]),
377 OscEnd {
378 data: &'a [u8],
379 used_bel: bool,
381 },
382 OscCancel,
383}
384
385impl<'a> std::fmt::Debug for VTEvent<'a> {
386 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
387 use VTEvent::*;
388 match self {
389 Raw(s) => {
390 write!(f, "Raw('")?;
391 fmt_utf8_bytes_with_ascii_control(f, s)?;
392 write!(f, "')")?;
393 Ok(())
394 }
395 EscInvalid(esc_invalid) => esc_invalid.fmt(f),
396 C0(b) => write!(f, "C0({b:02x})"),
397 Esc(esc) => esc.fmt(f),
398 Ss2(ss2) => ss2.fmt(f),
399 Ss3(ss3) => ss3.fmt(f),
400 Csi(csi) => csi.fmt(f),
401 DcsStart(dcs_start) => dcs_start.fmt(f),
402 DcsData(s) | DcsEnd(s) => {
403 if matches!(self, DcsEnd(..)) {
404 write!(f, "DcsEnd('")?;
405 } else {
406 write!(f, "DcsData('")?;
407 }
408 fmt_utf8_bytes_with_ascii_control(f, s)?;
409 write!(f, "')")?;
410 Ok(())
411 }
412 DcsCancel => write!(f, "DcsCancel"),
413 OscStart => write!(f, "OscStart"),
414 OscData(s) | OscEnd { data: s, .. } => {
415 if matches!(self, OscEnd { .. }) {
416 write!(f, "OscEnd('")?;
417 } else {
418 write!(f, "OscData('")?;
419 }
420 fmt_utf8_bytes_with_ascii_control(f, s)?;
421 write!(f, "')")?;
422 Ok(())
423 }
424 OscCancel => write!(f, "OscCancel"),
425 }
426 }
427}
428
429impl<'a> VTEvent<'a> {
430 pub fn csi(&self) -> Option<CSI> {
431 match self {
432 VTEvent::Csi(csi) => Some(CSI {
433 private: csi.private,
434 params: csi.params,
435 intermediates: csi.intermediates,
436 final_byte: csi.final_byte,
437 }),
438 _ => None,
439 }
440 }
441
442 pub fn byte_len(&self) -> usize {
443 use VTEvent::*;
444
445 match self {
446 Raw(s) => s.len(),
447 C0(_) => 1,
448 Esc(esc) => esc.intermediates.len() + 2 + esc.private.is_some() as usize,
449 EscInvalid(esc_invalid) => {
450 use self::EscInvalid::*;
451 match esc_invalid {
452 One(..) => 2,
453 Two(..) => 3,
454 Three(..) => 4,
455 Four(..) => 5,
456 }
457 }
458 Ss2(_) => 3,
459 Ss3(_) => 3,
460 Csi(csi) => {
461 csi.private.is_some() as usize
462 + csi.params.byte_len()
463 + csi.intermediates.byte_len()
464 + 3
465 }
466 DcsStart(dcs_start) => {
467 dcs_start.private.is_some() as usize
468 + dcs_start.params.byte_len()
469 + dcs_start.intermediates.byte_len()
470 + 3
471 }
472 DcsData(s) => s.len(),
473 DcsEnd(s) => s.len() + 2,
474 DcsCancel => 1,
475 OscStart => 2,
476 OscData(s) => s.len(),
477 OscEnd { data, used_bel } => {
478 if *used_bel {
479 data.len() + 1
480 } else {
481 data.len() + 2
482 }
483 }
484 OscCancel => 1,
485 }
486 }
487
488 pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
494 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
495 use VTEvent::*;
496
497 let len = self.byte_len();
498
499 if len > buf.len() {
500 return Err(len);
501 }
502
503 match self {
504 Raw(s) | OscData(s) | DcsData(s) => {
505 buf[..s.len()].copy_from_slice(s);
506 }
507 EscInvalid(esc_invalid) => {
508 use self::EscInvalid::*;
509 buf[0] = ESC;
510 match esc_invalid {
511 One(b) => buf[1] = *b,
512 Two(b1, b2) => {
513 buf[1] = *b1;
514 buf[2] = *b2;
515 }
516 Three(b1, b2, b3) => {
517 buf[1] = *b1;
518 buf[2] = *b2;
519 buf[3] = *b3;
520 }
521 Four(b1, b2, b3, b4) => {
522 buf[1] = *b1;
523 buf[2] = *b2;
524 buf[3] = *b3;
525 buf[4] = *b4;
526 }
527 }
528 }
529 OscCancel | DcsCancel => {
530 buf[0] = CAN;
531 }
532 C0(b) => {
533 buf[0] = *b;
534 }
535 Ss2(ss2) => {
536 buf[0] = ESC;
537 buf[1] = SS2;
538 buf[2] = ss2.char;
539 }
540 Ss3(ss3) => {
541 buf[0] = ESC;
542 buf[1] = SS3;
543 buf[2] = ss3.char;
544 }
545 Esc(esc) => {
546 buf[0] = ESC;
547 if let Some(p) = esc.private {
548 buf[1] = p;
549 buf = &mut buf[1..];
550 }
551 buf[1..esc.intermediates.len() + 1]
552 .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
553 buf[esc.intermediates.len() + 1] = esc.final_byte;
554 }
555 Csi(csi) => {
556 buf[0] = ESC;
557 buf[1] = CSI;
558 buf = &mut buf[2..];
559 if let Some(p) = csi.private {
560 buf[0] = p;
561 buf = &mut buf[1..];
562 }
563 let mut params = csi.params.into_iter();
564 if let Some(param) = params.next() {
565 buf[..param.len()].copy_from_slice(param);
566 buf = &mut buf[param.len()..];
567 for param in params {
568 buf[0] = b';';
569 buf = &mut buf[1..];
570 buf[..param.len()].copy_from_slice(param);
571 buf = &mut buf[param.len()..];
572 }
573 }
574 buf[..csi.intermediates.len()]
575 .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
576 buf[csi.intermediates.len()] = csi.final_byte;
577 }
578 DcsStart(dcs_start) => {
579 buf[0] = ESC;
580 buf[1] = DCS;
581 buf = &mut buf[2..];
582 if let Some(p) = dcs_start.private {
583 buf[0] = p;
584 buf = &mut buf[1..];
585 }
586 let mut params = dcs_start.params.into_iter();
587 if let Some(param) = params.next() {
588 buf[..param.len()].copy_from_slice(param);
589 buf = &mut buf[param.len()..];
590 for param in params {
591 buf[0] = b';';
592 buf = &mut buf[1..];
593 buf[..param.len()].copy_from_slice(param);
594 buf = &mut buf[param.len()..];
595 }
596 }
597 buf[..dcs_start.intermediates.len()].copy_from_slice(
598 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
599 );
600 buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
601 }
602 DcsEnd(data) => {
603 buf[..data.len()].copy_from_slice(data);
604 buf = &mut buf[data.len()..];
605 buf[0] = ESC;
606 buf[1] = ST_FINAL;
607 }
608 OscStart => {
609 buf[0] = ESC;
610 buf[1] = OSC;
611 }
612 OscEnd { data, used_bel } => {
613 buf[..data.len()].copy_from_slice(data);
614 buf = &mut buf[data.len()..];
615 if *used_bel {
616 buf[0] = BEL;
617 } else {
618 buf[0] = ESC;
619 buf[1] = ST_FINAL
620 }
621 }
622 }
623
624 Ok(len)
625 }
626
627 pub fn to_owned(&self) -> VTOwnedEvent {
628 use VTEvent::*;
629 match self {
630 Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
631 C0(b) => VTOwnedEvent::C0(*b),
632 Esc(esc) => VTOwnedEvent::Esc(*esc),
633 EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
634 Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
635 Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
636 Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
637 private: csi.private,
638 params: csi.params.to_owned(),
639 intermediates: csi.intermediates,
640 final_byte: csi.final_byte,
641 }),
642 DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
643 private: dcs_start.private,
644 params: dcs_start.params.to_owned(),
645 intermediates: dcs_start.intermediates,
646 final_byte: dcs_start.final_byte,
647 }),
648 DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
649 DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
650 DcsCancel => VTOwnedEvent::DcsCancel,
651 OscStart => VTOwnedEvent::OscStart,
652 OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
653 OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
654 data: data.to_vec(),
655 used_bel: *used_bel,
656 },
657 OscCancel => VTOwnedEvent::OscCancel,
658 }
659 }
660}
661
662#[cfg_attr(feature = "serde", derive(serde::Serialize))]
663#[derive(Clone, PartialEq, Eq, Debug, Default)]
664pub struct ParamBufOwned {
665 pub(crate) params: Params,
666}
667
668impl IntoIterator for ParamBufOwned {
669 type Item = Param;
670 type IntoIter = <Params as IntoIterator>::IntoIter;
671 fn into_iter(self) -> Self::IntoIter {
672 self.params.into_iter()
673 }
674}
675
676impl<'b> IntoIterator for &'b ParamBufOwned {
677 type Item = &'b [u8];
678 type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
679 fn into_iter(self) -> Self::IntoIter {
680 self.params.iter().map(|p| p.as_slice())
681 }
682}
683
684impl ParamBufOwned {
685 pub const fn empty() -> Self {
687 Self {
688 params: SmallVec::new_const(),
689 }
690 }
691
692 pub fn new(params: &[&[u8]]) -> Self {
694 Self {
695 params: params.iter().map(|p| Param::from(*p)).collect(),
696 }
697 }
698
699 pub fn len(&self) -> usize {
700 self.params.len()
701 }
702
703 pub fn is_empty(&self) -> bool {
704 self.params.is_empty()
705 }
706
707 pub fn get(&self, index: usize) -> Option<&[u8]> {
708 self.params.get(index).map(|p| p.as_slice())
709 }
710
711 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
712 self.params.get(index).and_then(|p| {
713 std::str::from_utf8(p.as_slice())
714 .ok()
715 .and_then(|s| s.parse::<T>().ok())
716 })
717 }
718
719 pub fn borrow(&self) -> ParamBuf<'_> {
720 ParamBuf {
721 params: &self.params,
722 }
723 }
724
725 pub fn numeric(&self) -> NumericParamBuf<'_> {
726 NumericParamBuf {
727 params: &self.params,
728 }
729 }
730}
731
732#[cfg_attr(feature = "serde", derive(serde::Serialize))]
735#[derive(Clone, PartialEq, Eq)]
736pub enum VTOwnedEvent {
737 Raw(Vec<u8>),
738 C0(u8),
739 Esc(Esc),
740 EscInvalid(EscInvalid),
741 Ss2(SS2),
742 Ss3(SS3),
743 Csi(CSIOwned),
744 DcsStart(DCSOwned),
745 DcsData(Vec<u8>),
746 DcsEnd(Vec<u8>),
747 DcsCancel,
748 OscStart,
749 OscData(Vec<u8>),
750 OscEnd { data: Vec<u8>, used_bel: bool },
751 OscCancel,
752}
753
754impl std::fmt::Debug for VTOwnedEvent {
755 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
756 self.borrow().fmt(f)
757 }
758}
759
760impl VTOwnedEvent {
761 pub fn borrow(&self) -> VTEvent<'_> {
762 match self {
763 VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
764 VTOwnedEvent::C0(b) => VTEvent::C0(*b),
765 VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
766 VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
767 VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
768 VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
769 VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
770 private: csi.private,
771 params: csi.params.borrow(),
772 intermediates: csi.intermediates,
773 final_byte: csi.final_byte,
774 }),
775 VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
776 private: dcs_start.private,
777 params: dcs_start.params.borrow(),
778 intermediates: dcs_start.intermediates,
779 final_byte: dcs_start.final_byte,
780 }),
781 VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
782 VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
783 VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
784 VTOwnedEvent::OscStart => VTEvent::OscStart,
785 VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
786 VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
787 data,
788 used_bel: *used_bel,
789 },
790 VTOwnedEvent::OscCancel => VTEvent::OscCancel,
791 }
792 }
793}
794
795#[cfg_attr(feature = "serde", derive(serde::Serialize))]
797#[derive(Clone, Copy, PartialEq, Eq)]
798pub enum EscInvalid {
799 One(u8),
800 Two(u8, u8),
801 Three(u8, u8, u8),
802 Four(u8, u8, u8, u8),
803}
804
805impl std::fmt::Debug for EscInvalid {
806 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
807 match self {
808 EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
809 EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
810 EscInvalid::Three(b1, b2, b3) => {
811 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
812 }
813 EscInvalid::Four(b1, b2, b3, b4) => {
814 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
815 }
816 }
817 Ok(())
818 }
819}
820
821#[cfg_attr(feature = "serde", derive(serde::Serialize))]
822#[derive(Clone, Copy, PartialEq, Eq)]
823pub struct Esc {
824 pub intermediates: VTIntermediate,
825 pub private: Option<u8>,
826 pub final_byte: u8,
827}
828
829impl std::fmt::Debug for Esc {
830 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
831 write!(f, "Esc(")?;
832 if let Some(p) = self.private {
833 write!(f, "{:?}, ", p as char)?;
834 }
835 write!(f, "{:?}, ", self.intermediates)?;
836 if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
837 write!(f, "{c})")?;
838 } else {
839 write!(f, "{})", self.final_byte as char)?;
840 }
841 Ok(())
842 }
843}
844
845#[cfg_attr(feature = "serde", derive(serde::Serialize))]
846#[derive(Clone, Copy, PartialEq, Eq)]
847pub struct SS2 {
848 pub char: u8,
849}
850
851impl std::fmt::Debug for SS2 {
852 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
853 write!(f, "Ss2(")?;
854 if let Ok(c) = AsciiControl::try_from(self.char as char) {
855 write!(f, "{c})")?;
856 } else {
857 write!(f, "{:?})", self.char as char)?;
858 }
859 Ok(())
860 }
861}
862
863#[cfg_attr(feature = "serde", derive(serde::Serialize))]
864#[derive(Clone, Copy, PartialEq, Eq)]
865pub struct SS3 {
866 pub char: u8,
867}
868
869impl std::fmt::Debug for SS3 {
870 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
871 write!(f, "Ss3(")?;
872 if let Ok(c) = AsciiControl::try_from(self.char as char) {
873 write!(f, "{c})")?;
874 } else {
875 write!(f, "{:?})", self.char as char)?;
876 }
877 Ok(())
878 }
879}
880
881#[cfg_attr(feature = "serde", derive(serde::Serialize))]
882#[derive(Clone, PartialEq, Eq)]
883pub struct CSI<'a> {
884 pub private: Option<u8>,
885 pub params: ParamBuf<'a>,
886 pub intermediates: VTIntermediate,
887 pub final_byte: u8,
888}
889
890impl<'a> std::fmt::Debug for CSI<'a> {
891 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
892 write!(f, "Csi(")?;
893 if let Some(p) = self.private {
894 write!(f, "{:?}, ", p as char)?;
895 }
896 for param in &self.params {
897 write!(f, "'")?;
898 fmt_utf8_bytes_simple(f, param)?;
899 write!(f, "', ")?;
900 }
901 write!(f, "{:?}, ", self.intermediates)?;
902 write!(f, "{:?})", self.final_byte as char)?;
903 Ok(())
904 }
905}
906
907#[cfg_attr(feature = "serde", derive(serde::Serialize))]
908#[derive(Clone, PartialEq, Eq)]
909pub struct DCS<'a> {
910 pub private: Option<u8>,
911 pub params: ParamBuf<'a>,
912 pub intermediates: VTIntermediate,
913 pub final_byte: u8,
914}
915
916impl<'a> std::fmt::Debug for DCS<'a> {
917 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
918 write!(f, "DcsStart(")?;
919 if let Some(p) = self.private {
920 write!(f, "{:?}, ", p as char)?;
921 }
922 for param in &self.params {
923 write!(f, "'")?;
924 fmt_utf8_bytes_simple(f, param)?;
925 write!(f, "', ")?;
926 }
927 write!(f, "{:?}, ", self.intermediates)?;
928 write!(f, "{})", self.final_byte as char)?;
929 Ok(())
930 }
931}
932
933#[cfg_attr(feature = "serde", derive(serde::Serialize))]
934#[derive(Clone, PartialEq, Eq)]
935pub struct CSIOwned {
936 pub private: Option<u8>,
937 pub params: ParamBufOwned,
938 pub intermediates: VTIntermediate,
939 pub final_byte: u8,
940}
941
942impl std::fmt::Debug for CSIOwned {
943 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
944 write!(f, "Csi(")?;
945 if let Some(p) = self.private {
946 write!(f, "{:?}", p as char)?;
947 }
948 for param in &self.params {
949 write!(f, ", '")?;
950 fmt_utf8_bytes_simple(f, param)?;
951 write!(f, "'")?;
952 }
953 write!(f, ", {:?}", self.intermediates)?;
954 write!(f, ", {:?})", self.final_byte as char)?;
955 Ok(())
956 }
957}
958
959#[cfg_attr(feature = "serde", derive(serde::Serialize))]
960#[derive(Clone, PartialEq, Eq)]
961pub struct DCSOwned {
962 pub private: Option<u8>,
963 pub params: ParamBufOwned,
964 pub intermediates: VTIntermediate,
965 pub final_byte: u8,
966}
967
968impl std::fmt::Debug for DCSOwned {
969 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
970 write!(f, "DcsStart(")?;
971 if let Some(p) = self.private {
972 write!(f, "{:?}", p as char)?;
973 }
974 for param in &self.params {
975 write!(f, ", '")?;
976 fmt_utf8_bytes_simple(f, param)?;
977 write!(f, "'")?;
978 }
979 write!(f, ", {:?}", self.intermediates)?;
980 write!(f, ", {})", self.final_byte as char)?;
981 Ok(())
982 }
983}
984
985#[cfg(test)]
986mod test {
987 use super::*;
988
989 #[test]
990 fn test_numeric_param_buf() {
991 let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
992 let numeric_param_buf = param_buf.numeric();
993 assert_eq!(
994 numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
995 vec![Some(1), Some(2), Some(3), Some(4), None, None]
996 );
997
998 assert_eq!(
999 numeric_param_buf
1000 .try_write(&mut [0, 0, 0, 0, 0, 0])
1001 .unwrap(),
1002 &[0, 4, 0]
1003 );
1004 assert_eq!(
1005 numeric_param_buf
1006 .get(0)
1007 .unwrap()
1008 .try_write(&mut [0, 0, 0, 0, 0, 0])
1009 .unwrap(),
1010 &[1, 2, 3]
1011 );
1012 }
1013}