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 Some(s) = std::str::from_utf8(self.param).ok() {
223 if let Ok(n) = s.parse::<u16>() {
224 Some(n)
225 } else {
226 None
227 }
228 } else {
229 None
230 }
231 } else {
232 None
233 }
234 }
235
236 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
243 let len = self.param.into_iter().filter(|p| **p == b':').count() + 1;
244 if buf.len() < len {
245 return Err(buf.len());
246 }
247 for (i, param) in self.into_iter().enumerate() {
248 buf[i] = param.unwrap_or(0);
249 }
250 Ok(&buf[..len])
251 }
252}
253
254impl<'a> IntoIterator for NumericParam<'a> {
255 type Item = Option<u16>;
256 type IntoIter = Map<std::slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> Option<u16>>;
257 fn into_iter(self) -> Self::IntoIter {
258 let fn1: fn(&u8) -> bool = |c: &u8| *c == b':';
259 self.param.split(fn1).map(|p| {
260 if p.is_empty() {
261 None
262 } else {
263 std::str::from_utf8(p)
264 .ok()
265 .and_then(|s| s.parse::<u16>().ok())
266 }
267 })
268 }
269}
270
271#[derive(Debug, Copy, Clone)]
276pub struct NumericParamBuf<'a> {
277 pub(crate) params: &'a Params,
278}
279
280impl<'a> IntoIterator for NumericParamBuf<'a> {
281 type Item = NumericParam<'a>;
282 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&'a Param) -> NumericParam<'a>>;
283 fn into_iter(self) -> Self::IntoIter {
284 self.params.iter().map(|p| NumericParam {
285 param: p.as_slice(),
286 })
287 }
288}
289
290impl<'a> NumericParamBuf<'a> {
291 pub const fn empty() -> Self {
292 NumericParamBuf {
293 params: &EMPTY_PARAMS,
294 }
295 }
296
297 pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
304 let len = self.params.len();
305 if buf.len() < len {
306 return Err(buf.len());
307 }
308 for (i, param) in self.into_iter().enumerate() {
309 buf[i] = param.sole().unwrap_or(0);
310 }
311 Ok(&buf[..len])
312 }
313
314 pub fn get(&self, index: usize) -> Option<NumericParam<'a>> {
315 self.params.get(index).map(|p| NumericParam {
316 param: p.as_slice(),
317 })
318 }
319}
320
321#[cfg_attr(feature = "serde", derive(serde::Serialize))]
324#[derive(Clone, PartialEq, Eq)]
325pub enum VTEvent<'a> {
326 Raw(&'a [u8]),
328
329 C0(u8),
331
332 Esc(Esc),
334
335 EscInvalid(EscInvalid),
337
338 Ss2(SS2),
340
341 Ss3(SS3),
343
344 Csi(CSI<'a>),
346
347 DcsStart(DCS<'a>),
349 DcsData(&'a [u8]),
350 DcsEnd(&'a [u8]),
351 DcsCancel,
352
353 OscStart,
355 OscData(&'a [u8]),
356 OscEnd {
357 data: &'a [u8],
358 used_bel: bool,
360 },
361 OscCancel,
362}
363
364impl<'a> std::fmt::Debug for VTEvent<'a> {
365 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
366 use VTEvent::*;
367 match self {
368 Raw(s) => {
369 write!(f, "Raw('")?;
370 fmt_utf8_bytes_with_ascii_control(f, s)?;
371 write!(f, "')")?;
372 Ok(())
373 }
374 EscInvalid(esc_invalid) => esc_invalid.fmt(f),
375 C0(b) => write!(f, "C0({b:02x})"),
376 Esc(esc) => esc.fmt(f),
377 Ss2(ss2) => ss2.fmt(f),
378 Ss3(ss3) => ss3.fmt(f),
379 Csi(csi) => csi.fmt(f),
380 DcsStart(dcs_start) => dcs_start.fmt(f),
381 DcsData(s) | DcsEnd(s) => {
382 if matches!(self, DcsEnd(..)) {
383 write!(f, "DcsEnd('")?;
384 } else {
385 write!(f, "DcsData('")?;
386 }
387 fmt_utf8_bytes_with_ascii_control(f, s)?;
388 write!(f, "')")?;
389 Ok(())
390 }
391 DcsCancel => write!(f, "DcsCancel"),
392 OscStart => write!(f, "OscStart"),
393 OscData(s) | OscEnd { data: s, .. } => {
394 if matches!(self, OscEnd { .. }) {
395 write!(f, "OscEnd('")?;
396 } else {
397 write!(f, "OscData('")?;
398 }
399 fmt_utf8_bytes_with_ascii_control(f, s)?;
400 write!(f, "')")?;
401 Ok(())
402 }
403 OscCancel => write!(f, "OscCancel"),
404 }
405 }
406}
407
408impl<'a> VTEvent<'a> {
409 pub fn csi(&self) -> Option<CSI> {
410 match self {
411 VTEvent::Csi(csi) => Some(CSI {
412 private: csi.private,
413 params: csi.params,
414 intermediates: csi.intermediates,
415 final_byte: csi.final_byte,
416 }),
417 _ => None,
418 }
419 }
420
421 pub fn byte_len(&self) -> usize {
422 use VTEvent::*;
423
424 match self {
425 Raw(s) => s.len(),
426 C0(_) => 1,
427 Esc(esc) => esc.intermediates.len() + 2 + esc.private.is_some() as usize,
428 EscInvalid(esc_invalid) => {
429 use self::EscInvalid::*;
430 match esc_invalid {
431 One(..) => 2,
432 Two(..) => 3,
433 Three(..) => 4,
434 Four(..) => 5,
435 }
436 }
437 Ss2(_) => 3,
438 Ss3(_) => 3,
439 Csi(csi) => {
440 csi.private.is_some() as usize
441 + csi.params.byte_len()
442 + csi.intermediates.byte_len()
443 + 3
444 }
445 DcsStart(dcs_start) => {
446 dcs_start.private.is_some() as usize
447 + dcs_start.params.byte_len()
448 + dcs_start.intermediates.byte_len()
449 + 3
450 }
451 DcsData(s) => s.len(),
452 DcsEnd(s) => s.len() + 2,
453 DcsCancel => 1,
454 OscStart => 2,
455 OscData(s) => s.len(),
456 OscEnd { data, used_bel } => {
457 if *used_bel {
458 data.len() + 1
459 } else {
460 data.len() + 2
461 }
462 }
463 OscCancel => 1,
464 }
465 }
466
467 pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
473 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
474 use VTEvent::*;
475
476 let len = self.byte_len();
477
478 if len > buf.len() {
479 return Err(len);
480 }
481
482 match self {
483 Raw(s) | OscData(s) | DcsData(s) => {
484 buf[..s.len()].copy_from_slice(s);
485 }
486 EscInvalid(esc_invalid) => {
487 use self::EscInvalid::*;
488 buf[0] = ESC;
489 match esc_invalid {
490 One(b) => buf[1] = *b,
491 Two(b1, b2) => {
492 buf[1] = *b1;
493 buf[2] = *b2;
494 }
495 Three(b1, b2, b3) => {
496 buf[1] = *b1;
497 buf[2] = *b2;
498 buf[3] = *b3;
499 }
500 Four(b1, b2, b3, b4) => {
501 buf[1] = *b1;
502 buf[2] = *b2;
503 buf[3] = *b3;
504 buf[4] = *b4;
505 }
506 }
507 }
508 OscCancel | DcsCancel => {
509 buf[0] = CAN;
510 }
511 C0(b) => {
512 buf[0] = *b;
513 }
514 Ss2(ss2) => {
515 buf[0] = ESC;
516 buf[1] = SS2;
517 buf[2] = ss2.char;
518 }
519 Ss3(ss3) => {
520 buf[0] = ESC;
521 buf[1] = SS3;
522 buf[2] = ss3.char;
523 }
524 Esc(esc) => {
525 buf[0] = ESC;
526 if let Some(p) = esc.private {
527 buf[1] = p;
528 buf = &mut buf[1..];
529 }
530 buf[1..esc.intermediates.len() + 1]
531 .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
532 buf[esc.intermediates.len() + 1] = esc.final_byte;
533 }
534 Csi(csi) => {
535 buf[0] = ESC;
536 buf[1] = CSI;
537 buf = &mut buf[2..];
538 if let Some(p) = csi.private {
539 buf[0] = p;
540 buf = &mut buf[1..];
541 }
542 let mut params = csi.params.into_iter();
543 if let Some(param) = params.next() {
544 buf[..param.len()].copy_from_slice(param);
545 buf = &mut buf[param.len()..];
546 for param in params {
547 buf[0] = b';';
548 buf = &mut buf[1..];
549 buf[..param.len()].copy_from_slice(param);
550 buf = &mut buf[param.len()..];
551 }
552 }
553 buf[..csi.intermediates.len()]
554 .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
555 buf[csi.intermediates.len()] = csi.final_byte;
556 }
557 DcsStart(dcs_start) => {
558 buf[0] = ESC;
559 buf[1] = DCS;
560 buf = &mut buf[2..];
561 if let Some(p) = dcs_start.private {
562 buf[0] = p;
563 buf = &mut buf[1..];
564 }
565 let mut params = dcs_start.params.into_iter();
566 if let Some(param) = params.next() {
567 buf[..param.len()].copy_from_slice(param);
568 buf = &mut buf[param.len()..];
569 for param in params {
570 buf[0] = b';';
571 buf = &mut buf[1..];
572 buf[..param.len()].copy_from_slice(param);
573 buf = &mut buf[param.len()..];
574 }
575 }
576 buf[..dcs_start.intermediates.len()].copy_from_slice(
577 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
578 );
579 buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
580 }
581 DcsEnd(data) => {
582 buf[..data.len()].copy_from_slice(data);
583 buf = &mut buf[data.len()..];
584 buf[0] = ESC;
585 buf[1] = ST_FINAL;
586 }
587 OscStart => {
588 buf[0] = ESC;
589 buf[1] = OSC;
590 }
591 OscEnd { data, used_bel } => {
592 buf[..data.len()].copy_from_slice(data);
593 buf = &mut buf[data.len()..];
594 if *used_bel {
595 buf[0] = BEL;
596 } else {
597 buf[0] = ESC;
598 buf[1] = ST_FINAL
599 }
600 }
601 }
602
603 Ok(len)
604 }
605
606 pub fn to_owned(&self) -> VTOwnedEvent {
607 use VTEvent::*;
608 match self {
609 Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
610 C0(b) => VTOwnedEvent::C0(*b),
611 Esc(esc) => VTOwnedEvent::Esc(*esc),
612 EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
613 Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
614 Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
615 Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
616 private: csi.private,
617 params: csi.params.to_owned(),
618 intermediates: csi.intermediates,
619 final_byte: csi.final_byte,
620 }),
621 DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
622 private: dcs_start.private,
623 params: dcs_start.params.to_owned(),
624 intermediates: dcs_start.intermediates,
625 final_byte: dcs_start.final_byte,
626 }),
627 DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
628 DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
629 DcsCancel => VTOwnedEvent::DcsCancel,
630 OscStart => VTOwnedEvent::OscStart,
631 OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
632 OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
633 data: data.to_vec(),
634 used_bel: *used_bel,
635 },
636 OscCancel => VTOwnedEvent::OscCancel,
637 }
638 }
639}
640
641#[cfg_attr(feature = "serde", derive(serde::Serialize))]
642#[derive(Clone, PartialEq, Eq, Debug, Default)]
643pub struct ParamBufOwned {
644 pub(crate) params: Params,
645}
646
647impl IntoIterator for ParamBufOwned {
648 type Item = Param;
649 type IntoIter = <Params as IntoIterator>::IntoIter;
650 fn into_iter(self) -> Self::IntoIter {
651 self.params.into_iter()
652 }
653}
654
655impl<'b> IntoIterator for &'b ParamBufOwned {
656 type Item = &'b [u8];
657 type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
658 fn into_iter(self) -> Self::IntoIter {
659 self.params.iter().map(|p| p.as_slice())
660 }
661}
662
663impl ParamBufOwned {
664 pub const fn empty() -> Self {
666 Self {
667 params: SmallVec::new_const(),
668 }
669 }
670
671 pub fn new(params: &[&[u8]]) -> Self {
673 Self {
674 params: params.iter().map(|p| Param::from(*p)).collect(),
675 }
676 }
677
678 pub fn len(&self) -> usize {
679 self.params.len()
680 }
681
682 pub fn is_empty(&self) -> bool {
683 self.params.is_empty()
684 }
685
686 pub fn get(&self, index: usize) -> Option<&[u8]> {
687 self.params.get(index).map(|p| p.as_slice())
688 }
689
690 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
691 self.params.get(index).and_then(|p| {
692 std::str::from_utf8(p.as_slice())
693 .ok()
694 .and_then(|s| s.parse::<T>().ok())
695 })
696 }
697
698 pub fn borrow(&self) -> ParamBuf<'_> {
699 ParamBuf {
700 params: &self.params,
701 }
702 }
703
704 pub fn numeric(&self) -> NumericParamBuf<'_> {
705 NumericParamBuf {
706 params: &self.params,
707 }
708 }
709}
710
711#[cfg_attr(feature = "serde", derive(serde::Serialize))]
714#[derive(Clone, PartialEq, Eq)]
715pub enum VTOwnedEvent {
716 Raw(Vec<u8>),
717 C0(u8),
718 Esc(Esc),
719 EscInvalid(EscInvalid),
720 Ss2(SS2),
721 Ss3(SS3),
722 Csi(CSIOwned),
723 DcsStart(DCSOwned),
724 DcsData(Vec<u8>),
725 DcsEnd(Vec<u8>),
726 DcsCancel,
727 OscStart,
728 OscData(Vec<u8>),
729 OscEnd { data: Vec<u8>, used_bel: bool },
730 OscCancel,
731}
732
733impl std::fmt::Debug for VTOwnedEvent {
734 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
735 self.borrow().fmt(f)
736 }
737}
738
739impl VTOwnedEvent {
740 pub fn borrow(&self) -> VTEvent<'_> {
741 match self {
742 VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
743 VTOwnedEvent::C0(b) => VTEvent::C0(*b),
744 VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
745 VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
746 VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
747 VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
748 VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
749 private: csi.private,
750 params: csi.params.borrow(),
751 intermediates: csi.intermediates,
752 final_byte: csi.final_byte,
753 }),
754 VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
755 private: dcs_start.private,
756 params: dcs_start.params.borrow(),
757 intermediates: dcs_start.intermediates,
758 final_byte: dcs_start.final_byte,
759 }),
760 VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
761 VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
762 VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
763 VTOwnedEvent::OscStart => VTEvent::OscStart,
764 VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
765 VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
766 data,
767 used_bel: *used_bel,
768 },
769 VTOwnedEvent::OscCancel => VTEvent::OscCancel,
770 }
771 }
772}
773
774#[cfg_attr(feature = "serde", derive(serde::Serialize))]
776#[derive(Clone, Copy, PartialEq, Eq)]
777pub enum EscInvalid {
778 One(u8),
779 Two(u8, u8),
780 Three(u8, u8, u8),
781 Four(u8, u8, u8, u8),
782}
783
784impl std::fmt::Debug for EscInvalid {
785 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
786 match self {
787 EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
788 EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
789 EscInvalid::Three(b1, b2, b3) => {
790 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
791 }
792 EscInvalid::Four(b1, b2, b3, b4) => {
793 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
794 }
795 }
796 Ok(())
797 }
798}
799
800#[cfg_attr(feature = "serde", derive(serde::Serialize))]
801#[derive(Clone, Copy, PartialEq, Eq)]
802pub struct Esc {
803 pub intermediates: VTIntermediate,
804 pub private: Option<u8>,
805 pub final_byte: u8,
806}
807
808impl std::fmt::Debug for Esc {
809 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
810 write!(f, "Esc(")?;
811 if let Some(p) = self.private {
812 write!(f, "{:?}, ", p as char)?;
813 }
814 write!(f, "{:?}, ", self.intermediates)?;
815 if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
816 write!(f, "{c})")?;
817 } else {
818 write!(f, "{})", self.final_byte as char)?;
819 }
820 Ok(())
821 }
822}
823
824#[cfg_attr(feature = "serde", derive(serde::Serialize))]
825#[derive(Clone, Copy, PartialEq, Eq)]
826pub struct SS2 {
827 pub char: u8,
828}
829
830impl std::fmt::Debug for SS2 {
831 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
832 write!(f, "Ss2(")?;
833 if let Ok(c) = AsciiControl::try_from(self.char as char) {
834 write!(f, "{c})")?;
835 } else {
836 write!(f, "{:?})", self.char as char)?;
837 }
838 Ok(())
839 }
840}
841
842#[cfg_attr(feature = "serde", derive(serde::Serialize))]
843#[derive(Clone, Copy, PartialEq, Eq)]
844pub struct SS3 {
845 pub char: u8,
846}
847
848impl std::fmt::Debug for SS3 {
849 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
850 write!(f, "Ss3(")?;
851 if let Ok(c) = AsciiControl::try_from(self.char as char) {
852 write!(f, "{c})")?;
853 } else {
854 write!(f, "{:?})", self.char as char)?;
855 }
856 Ok(())
857 }
858}
859
860#[cfg_attr(feature = "serde", derive(serde::Serialize))]
861#[derive(Clone, PartialEq, Eq)]
862pub struct CSI<'a> {
863 pub private: Option<u8>,
864 pub params: ParamBuf<'a>,
865 pub intermediates: VTIntermediate,
866 pub final_byte: u8,
867}
868
869impl<'a> std::fmt::Debug for CSI<'a> {
870 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
871 write!(f, "Csi(")?;
872 if let Some(p) = self.private {
873 write!(f, "{:?}, ", p as char)?;
874 }
875 for param in &self.params {
876 write!(f, "'")?;
877 fmt_utf8_bytes_simple(f, param)?;
878 write!(f, "', ")?;
879 }
880 write!(f, "{:?}, ", self.intermediates)?;
881 write!(f, "{:?})", self.final_byte as char)?;
882 Ok(())
883 }
884}
885
886#[cfg_attr(feature = "serde", derive(serde::Serialize))]
887#[derive(Clone, PartialEq, Eq)]
888pub struct DCS<'a> {
889 pub private: Option<u8>,
890 pub params: ParamBuf<'a>,
891 pub intermediates: VTIntermediate,
892 pub final_byte: u8,
893}
894
895impl<'a> std::fmt::Debug for DCS<'a> {
896 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
897 write!(f, "DcsStart(")?;
898 if let Some(p) = self.private {
899 write!(f, "{:?}, ", p as char)?;
900 }
901 for param in &self.params {
902 write!(f, "'")?;
903 fmt_utf8_bytes_simple(f, param)?;
904 write!(f, "', ")?;
905 }
906 write!(f, "{:?}, ", self.intermediates)?;
907 write!(f, "{})", self.final_byte as char)?;
908 Ok(())
909 }
910}
911
912#[cfg_attr(feature = "serde", derive(serde::Serialize))]
913#[derive(Clone, PartialEq, Eq)]
914pub struct CSIOwned {
915 pub private: Option<u8>,
916 pub params: ParamBufOwned,
917 pub intermediates: VTIntermediate,
918 pub final_byte: u8,
919}
920
921impl std::fmt::Debug for CSIOwned {
922 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
923 write!(f, "Csi(")?;
924 if let Some(p) = self.private {
925 write!(f, "{:?}", p as char)?;
926 }
927 for param in &self.params {
928 write!(f, ", '")?;
929 fmt_utf8_bytes_simple(f, param)?;
930 write!(f, "'")?;
931 }
932 write!(f, ", {:?}", self.intermediates)?;
933 write!(f, ", {:?})", self.final_byte as char)?;
934 Ok(())
935 }
936}
937
938#[cfg_attr(feature = "serde", derive(serde::Serialize))]
939#[derive(Clone, PartialEq, Eq)]
940pub struct DCSOwned {
941 pub private: Option<u8>,
942 pub params: ParamBufOwned,
943 pub intermediates: VTIntermediate,
944 pub final_byte: u8,
945}
946
947impl std::fmt::Debug for DCSOwned {
948 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
949 write!(f, "DcsStart(")?;
950 if let Some(p) = self.private {
951 write!(f, "{:?}", p as char)?;
952 }
953 for param in &self.params {
954 write!(f, ", '")?;
955 fmt_utf8_bytes_simple(f, param)?;
956 write!(f, "'")?;
957 }
958 write!(f, ", {:?}", self.intermediates)?;
959 write!(f, ", {})", self.final_byte as char)?;
960 Ok(())
961 }
962}
963
964#[cfg(test)]
965mod test {
966 use super::*;
967
968 #[test]
969 fn test_numeric_param_buf() {
970 let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
971 let numeric_param_buf = param_buf.numeric();
972 assert_eq!(
973 numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
974 vec![Some(1), Some(2), Some(3), Some(4), None, None]
975 );
976
977 assert_eq!(
978 numeric_param_buf
979 .try_write(&mut [0, 0, 0, 0, 0, 0])
980 .unwrap(),
981 &[0, 4, 0]
982 );
983 assert_eq!(
984 numeric_param_buf
985 .get(0)
986 .unwrap()
987 .try_write(&mut [0, 0, 0, 0, 0, 0])
988 .unwrap(),
989 &[1, 2, 3]
990 );
991 }
992}