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
143#[cfg_attr(feature = "serde", derive(serde::Serialize))]
144#[derive(Debug, Copy, Clone, PartialEq, Eq)]
145#[repr(transparent)]
146pub struct ParamBuf<'a> {
147 pub(crate) params: &'a Params,
148}
149
150impl<'a> IntoIterator for ParamBuf<'a> {
151 type Item = &'a [u8];
152 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
153 fn into_iter(self) -> Self::IntoIter {
154 self.params.iter().map(|p| p.as_slice())
155 }
156}
157
158impl<'a> IntoIterator for &ParamBuf<'a> {
159 type Item = &'a [u8];
160 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
161 fn into_iter(self) -> Self::IntoIter {
162 self.params.iter().map(|p| p.as_slice())
163 }
164}
165
166impl<'a> ParamBuf<'a> {
167 pub fn len(&self) -> usize {
168 self.params.len()
169 }
170
171 pub fn is_empty(&self) -> bool {
172 self.params.is_empty()
173 }
174
175 pub fn get(&self, index: usize) -> Option<&[u8]> {
176 self.params.get(index).map(|p| p.as_slice())
177 }
178
179 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
180 self.params.get(index).and_then(|p| {
181 std::str::from_utf8(p.as_slice())
182 .ok()
183 .and_then(|s| s.parse::<T>().ok())
184 })
185 }
186
187 pub fn to_owned(&self) -> ParamBufOwned {
188 ParamBufOwned {
189 params: self.params.iter().cloned().collect(),
190 }
191 }
192
193 pub fn byte_len(&self) -> usize {
194 self.params.iter().map(|p| p.len()).sum::<usize>() + self.params.len().saturating_sub(1)
195 }
196
197 pub fn numeric(&self) -> NumericParamBuf<'a> {
198 NumericParamBuf {
199 params: self.params,
200 }
201 }
202}
203
204pub struct NumericParam<'a> {
206 pub(crate) param: &'a [u8],
207}
208
209impl<'a> IntoIterator for NumericParam<'a> {
210 type Item = Option<u16>;
211 type IntoIter = Map<std::slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> Option<u16>>;
212 fn into_iter(self) -> Self::IntoIter {
213 let fn1: fn(&u8) -> bool = |c: &u8| *c == b':';
214 self.param.split(fn1).map(|p| {
215 if p.is_empty() {
216 None
217 } else {
218 std::str::from_utf8(p)
219 .ok()
220 .and_then(|s| s.parse::<u16>().ok())
221 }
222 })
223 }
224}
225
226pub struct NumericParamBuf<'a> {
231 pub(crate) params: &'a Params,
232}
233
234impl<'a> IntoIterator for NumericParamBuf<'a> {
235 type Item = NumericParam<'a>;
236 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&'a Param) -> NumericParam<'a>>;
237 fn into_iter(self) -> Self::IntoIter {
238 self.params.iter().map(|p| NumericParam {
239 param: p.as_slice(),
240 })
241 }
242}
243
244#[cfg_attr(feature = "serde", derive(serde::Serialize))]
247#[derive(Clone, PartialEq, Eq)]
248pub enum VTEvent<'a> {
249 Raw(&'a [u8]),
251
252 C0(u8),
254
255 Esc(Esc),
257
258 EscInvalid(EscInvalid),
260
261 Ss2(SS2),
263
264 Ss3(SS3),
266
267 Csi(CSI<'a>),
269
270 DcsStart(DCS<'a>),
272 DcsData(&'a [u8]),
273 DcsEnd(&'a [u8]),
274 DcsCancel,
275
276 OscStart,
278 OscData(&'a [u8]),
279 OscEnd {
280 data: &'a [u8],
281 used_bel: bool,
283 },
284 OscCancel,
285}
286
287impl<'a> std::fmt::Debug for VTEvent<'a> {
288 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
289 use VTEvent::*;
290 match self {
291 Raw(s) => {
292 write!(f, "Raw('")?;
293 fmt_utf8_bytes_with_ascii_control(f, s)?;
294 write!(f, "')")?;
295 Ok(())
296 }
297 EscInvalid(esc_invalid) => esc_invalid.fmt(f),
298 C0(b) => write!(f, "C0({b:02x})"),
299 Esc(esc) => esc.fmt(f),
300 Ss2(ss2) => ss2.fmt(f),
301 Ss3(ss3) => ss3.fmt(f),
302 Csi(csi) => csi.fmt(f),
303 DcsStart(dcs_start) => dcs_start.fmt(f),
304 DcsData(s) | DcsEnd(s) => {
305 if matches!(self, DcsEnd(..)) {
306 write!(f, "DcsEnd('")?;
307 } else {
308 write!(f, "DcsData('")?;
309 }
310 fmt_utf8_bytes_with_ascii_control(f, s)?;
311 write!(f, "')")?;
312 Ok(())
313 }
314 DcsCancel => write!(f, "DcsCancel"),
315 OscStart => write!(f, "OscStart"),
316 OscData(s) | OscEnd { data: s, .. } => {
317 if matches!(self, OscEnd { .. }) {
318 write!(f, "OscEnd('")?;
319 } else {
320 write!(f, "OscData('")?;
321 }
322 fmt_utf8_bytes_with_ascii_control(f, s)?;
323 write!(f, "')")?;
324 Ok(())
325 }
326 OscCancel => write!(f, "OscCancel"),
327 }
328 }
329}
330
331impl<'a> VTEvent<'a> {
332 pub fn csi(&self) -> Option<CSI> {
333 match self {
334 VTEvent::Csi(csi) => Some(CSI {
335 private: csi.private,
336 params: csi.params,
337 intermediates: csi.intermediates,
338 final_byte: csi.final_byte,
339 }),
340 _ => None,
341 }
342 }
343
344 pub fn byte_len(&self) -> usize {
345 use VTEvent::*;
346
347 match self {
348 Raw(s) => s.len(),
349 C0(_) => 1,
350 Esc(esc) => esc.intermediates.len() + 2 + esc.private.is_some() as usize,
351 EscInvalid(esc_invalid) => {
352 use self::EscInvalid::*;
353 match esc_invalid {
354 One(..) => 2,
355 Two(..) => 3,
356 Three(..) => 4,
357 Four(..) => 5,
358 }
359 }
360 Ss2(_) => 3,
361 Ss3(_) => 3,
362 Csi(csi) => {
363 csi.private.is_some() as usize
364 + csi.params.byte_len()
365 + csi.intermediates.byte_len()
366 + 3
367 }
368 DcsStart(dcs_start) => {
369 dcs_start.private.is_some() as usize
370 + dcs_start.params.byte_len()
371 + dcs_start.intermediates.byte_len()
372 + 3
373 }
374 DcsData(s) => s.len(),
375 DcsEnd(s) => s.len() + 2,
376 DcsCancel => 1,
377 OscStart => 2,
378 OscData(s) => s.len(),
379 OscEnd { data, used_bel } => {
380 if *used_bel {
381 data.len() + 1
382 } else {
383 data.len() + 2
384 }
385 }
386 OscCancel => 1,
387 }
388 }
389
390 pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
396 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
397 use VTEvent::*;
398
399 let len = self.byte_len();
400
401 if len > buf.len() {
402 return Err(len);
403 }
404
405 match self {
406 Raw(s) | OscData(s) | DcsData(s) => {
407 buf[..s.len()].copy_from_slice(s);
408 }
409 EscInvalid(esc_invalid) => {
410 use self::EscInvalid::*;
411 buf[0] = ESC;
412 match esc_invalid {
413 One(b) => buf[1] = *b,
414 Two(b1, b2) => {
415 buf[1] = *b1;
416 buf[2] = *b2;
417 }
418 Three(b1, b2, b3) => {
419 buf[1] = *b1;
420 buf[2] = *b2;
421 buf[3] = *b3;
422 }
423 Four(b1, b2, b3, b4) => {
424 buf[1] = *b1;
425 buf[2] = *b2;
426 buf[3] = *b3;
427 buf[4] = *b4;
428 }
429 }
430 }
431 OscCancel | DcsCancel => {
432 buf[0] = CAN;
433 }
434 C0(b) => {
435 buf[0] = *b;
436 }
437 Ss2(ss2) => {
438 buf[0] = ESC;
439 buf[1] = SS2;
440 buf[2] = ss2.char;
441 }
442 Ss3(ss3) => {
443 buf[0] = ESC;
444 buf[1] = SS3;
445 buf[2] = ss3.char;
446 }
447 Esc(esc) => {
448 buf[0] = ESC;
449 if let Some(p) = esc.private {
450 buf[1] = p;
451 buf = &mut buf[1..];
452 }
453 buf[1..esc.intermediates.len() + 1]
454 .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
455 buf[esc.intermediates.len() + 1] = esc.final_byte;
456 }
457 Csi(csi) => {
458 buf[0] = ESC;
459 buf[1] = CSI;
460 buf = &mut buf[2..];
461 if let Some(p) = csi.private {
462 buf[0] = p;
463 buf = &mut buf[1..];
464 }
465 let mut params = csi.params.into_iter();
466 if let Some(param) = params.next() {
467 buf[..param.len()].copy_from_slice(param);
468 buf = &mut buf[param.len()..];
469 for param in params {
470 buf[0] = b';';
471 buf = &mut buf[1..];
472 buf[..param.len()].copy_from_slice(param);
473 buf = &mut buf[param.len()..];
474 }
475 }
476 buf[..csi.intermediates.len()]
477 .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
478 buf[csi.intermediates.len()] = csi.final_byte;
479 }
480 DcsStart(dcs_start) => {
481 buf[0] = ESC;
482 buf[1] = DCS;
483 buf = &mut buf[2..];
484 if let Some(p) = dcs_start.private {
485 buf[0] = p;
486 buf = &mut buf[1..];
487 }
488 let mut params = dcs_start.params.into_iter();
489 if let Some(param) = params.next() {
490 buf[..param.len()].copy_from_slice(param);
491 buf = &mut buf[param.len()..];
492 for param in params {
493 buf[0] = b';';
494 buf = &mut buf[1..];
495 buf[..param.len()].copy_from_slice(param);
496 buf = &mut buf[param.len()..];
497 }
498 }
499 buf[..dcs_start.intermediates.len()].copy_from_slice(
500 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
501 );
502 buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
503 }
504 DcsEnd(data) => {
505 buf[..data.len()].copy_from_slice(data);
506 buf = &mut buf[data.len()..];
507 buf[0] = ESC;
508 buf[1] = ST_FINAL;
509 }
510 OscStart => {
511 buf[0] = ESC;
512 buf[1] = OSC;
513 }
514 OscEnd { data, used_bel } => {
515 buf[..data.len()].copy_from_slice(data);
516 buf = &mut buf[data.len()..];
517 if *used_bel {
518 buf[0] = BEL;
519 } else {
520 buf[0] = ESC;
521 buf[1] = ST_FINAL
522 }
523 }
524 }
525
526 Ok(len)
527 }
528
529 pub fn to_owned(&self) -> VTOwnedEvent {
530 use VTEvent::*;
531 match self {
532 Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
533 C0(b) => VTOwnedEvent::C0(*b),
534 Esc(esc) => VTOwnedEvent::Esc(*esc),
535 EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
536 Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
537 Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
538 Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
539 private: csi.private,
540 params: csi.params.to_owned(),
541 intermediates: csi.intermediates,
542 final_byte: csi.final_byte,
543 }),
544 DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
545 private: dcs_start.private,
546 params: dcs_start.params.to_owned(),
547 intermediates: dcs_start.intermediates,
548 final_byte: dcs_start.final_byte,
549 }),
550 DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
551 DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
552 DcsCancel => VTOwnedEvent::DcsCancel,
553 OscStart => VTOwnedEvent::OscStart,
554 OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
555 OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
556 data: data.to_vec(),
557 used_bel: *used_bel,
558 },
559 OscCancel => VTOwnedEvent::OscCancel,
560 }
561 }
562}
563
564#[cfg_attr(feature = "serde", derive(serde::Serialize))]
565#[derive(Clone, PartialEq, Eq, Debug, Default)]
566pub struct ParamBufOwned {
567 pub(crate) params: Params,
568}
569
570impl IntoIterator for ParamBufOwned {
571 type Item = Param;
572 type IntoIter = <Params as IntoIterator>::IntoIter;
573 fn into_iter(self) -> Self::IntoIter {
574 self.params.into_iter()
575 }
576}
577
578impl<'b> IntoIterator for &'b ParamBufOwned {
579 type Item = &'b [u8];
580 type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
581 fn into_iter(self) -> Self::IntoIter {
582 self.params.iter().map(|p| p.as_slice())
583 }
584}
585
586impl ParamBufOwned {
587 pub const fn empty() -> Self {
589 Self {
590 params: SmallVec::new_const(),
591 }
592 }
593
594 pub fn new(params: &[&[u8]]) -> Self {
596 Self {
597 params: params.iter().map(|p| Param::from(*p)).collect(),
598 }
599 }
600
601 pub fn len(&self) -> usize {
602 self.params.len()
603 }
604
605 pub fn is_empty(&self) -> bool {
606 self.params.is_empty()
607 }
608
609 pub fn get(&self, index: usize) -> Option<&[u8]> {
610 self.params.get(index).map(|p| p.as_slice())
611 }
612
613 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
614 self.params.get(index).and_then(|p| {
615 std::str::from_utf8(p.as_slice())
616 .ok()
617 .and_then(|s| s.parse::<T>().ok())
618 })
619 }
620
621 pub fn borrow(&self) -> ParamBuf<'_> {
622 ParamBuf {
623 params: &self.params,
624 }
625 }
626
627 pub fn numeric(&self) -> NumericParamBuf<'_> {
628 NumericParamBuf {
629 params: &self.params,
630 }
631 }
632}
633
634#[cfg_attr(feature = "serde", derive(serde::Serialize))]
637#[derive(Clone, PartialEq, Eq)]
638pub enum VTOwnedEvent {
639 Raw(Vec<u8>),
640 C0(u8),
641 Esc(Esc),
642 EscInvalid(EscInvalid),
643 Ss2(SS2),
644 Ss3(SS3),
645 Csi(CSIOwned),
646 DcsStart(DCSOwned),
647 DcsData(Vec<u8>),
648 DcsEnd(Vec<u8>),
649 DcsCancel,
650 OscStart,
651 OscData(Vec<u8>),
652 OscEnd { data: Vec<u8>, used_bel: bool },
653 OscCancel,
654}
655
656impl std::fmt::Debug for VTOwnedEvent {
657 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
658 self.borrow().fmt(f)
659 }
660}
661
662impl VTOwnedEvent {
663 pub fn borrow(&self) -> VTEvent<'_> {
664 match self {
665 VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
666 VTOwnedEvent::C0(b) => VTEvent::C0(*b),
667 VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
668 VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
669 VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
670 VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
671 VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
672 private: csi.private,
673 params: csi.params.borrow(),
674 intermediates: csi.intermediates,
675 final_byte: csi.final_byte,
676 }),
677 VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
678 private: dcs_start.private,
679 params: dcs_start.params.borrow(),
680 intermediates: dcs_start.intermediates,
681 final_byte: dcs_start.final_byte,
682 }),
683 VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
684 VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
685 VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
686 VTOwnedEvent::OscStart => VTEvent::OscStart,
687 VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
688 VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
689 data,
690 used_bel: *used_bel,
691 },
692 VTOwnedEvent::OscCancel => VTEvent::OscCancel,
693 }
694 }
695}
696
697#[cfg_attr(feature = "serde", derive(serde::Serialize))]
699#[derive(Clone, Copy, PartialEq, Eq)]
700pub enum EscInvalid {
701 One(u8),
702 Two(u8, u8),
703 Three(u8, u8, u8),
704 Four(u8, u8, u8, u8),
705}
706
707impl std::fmt::Debug for EscInvalid {
708 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
709 match self {
710 EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
711 EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
712 EscInvalid::Three(b1, b2, b3) => {
713 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
714 }
715 EscInvalid::Four(b1, b2, b3, b4) => {
716 write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
717 }
718 }
719 Ok(())
720 }
721}
722
723#[cfg_attr(feature = "serde", derive(serde::Serialize))]
724#[derive(Clone, Copy, PartialEq, Eq)]
725pub struct Esc {
726 pub intermediates: VTIntermediate,
727 pub private: Option<u8>,
728 pub final_byte: u8,
729}
730
731impl std::fmt::Debug for Esc {
732 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
733 write!(f, "Esc(")?;
734 if let Some(p) = self.private {
735 write!(f, "{:?}, ", p as char)?;
736 }
737 write!(f, "{:?}, ", self.intermediates)?;
738 if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
739 write!(f, "{c})")?;
740 } else {
741 write!(f, "{})", self.final_byte as char)?;
742 }
743 Ok(())
744 }
745}
746
747#[cfg_attr(feature = "serde", derive(serde::Serialize))]
748#[derive(Clone, Copy, PartialEq, Eq)]
749pub struct SS2 {
750 pub char: u8,
751}
752
753impl std::fmt::Debug for SS2 {
754 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
755 write!(f, "Ss2(")?;
756 if let Ok(c) = AsciiControl::try_from(self.char as char) {
757 write!(f, "{c})")?;
758 } else {
759 write!(f, "{:?})", self.char as char)?;
760 }
761 Ok(())
762 }
763}
764
765#[cfg_attr(feature = "serde", derive(serde::Serialize))]
766#[derive(Clone, Copy, PartialEq, Eq)]
767pub struct SS3 {
768 pub char: u8,
769}
770
771impl std::fmt::Debug for SS3 {
772 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
773 write!(f, "Ss3(")?;
774 if let Ok(c) = AsciiControl::try_from(self.char as char) {
775 write!(f, "{c})")?;
776 } else {
777 write!(f, "{:?})", self.char as char)?;
778 }
779 Ok(())
780 }
781}
782
783#[cfg_attr(feature = "serde", derive(serde::Serialize))]
784#[derive(Clone, PartialEq, Eq)]
785pub struct CSI<'a> {
786 pub private: Option<u8>,
787 pub params: ParamBuf<'a>,
788 pub intermediates: VTIntermediate,
789 pub final_byte: u8,
790}
791
792impl<'a> std::fmt::Debug for CSI<'a> {
793 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
794 write!(f, "Csi(")?;
795 if let Some(p) = self.private {
796 write!(f, "{:?}, ", p as char)?;
797 }
798 for param in &self.params {
799 write!(f, "'")?;
800 fmt_utf8_bytes_simple(f, param)?;
801 write!(f, "', ")?;
802 }
803 write!(f, "{:?}, ", self.intermediates)?;
804 write!(f, "{:?})", self.final_byte as char)?;
805 Ok(())
806 }
807}
808
809#[cfg_attr(feature = "serde", derive(serde::Serialize))]
810#[derive(Clone, PartialEq, Eq)]
811pub struct DCS<'a> {
812 pub private: Option<u8>,
813 pub params: ParamBuf<'a>,
814 pub intermediates: VTIntermediate,
815 pub final_byte: u8,
816}
817
818impl<'a> std::fmt::Debug for DCS<'a> {
819 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
820 write!(f, "DcsStart(")?;
821 if let Some(p) = self.private {
822 write!(f, "{:?}, ", p as char)?;
823 }
824 for param in &self.params {
825 write!(f, "'")?;
826 fmt_utf8_bytes_simple(f, param)?;
827 write!(f, "', ")?;
828 }
829 write!(f, "{:?}, ", self.intermediates)?;
830 write!(f, "{})", self.final_byte as char)?;
831 Ok(())
832 }
833}
834
835#[cfg_attr(feature = "serde", derive(serde::Serialize))]
836#[derive(Clone, PartialEq, Eq)]
837pub struct CSIOwned {
838 pub private: Option<u8>,
839 pub params: ParamBufOwned,
840 pub intermediates: VTIntermediate,
841 pub final_byte: u8,
842}
843
844impl std::fmt::Debug for CSIOwned {
845 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
846 write!(f, "Csi(")?;
847 if let Some(p) = self.private {
848 write!(f, "{:?}", p as char)?;
849 }
850 for param in &self.params {
851 write!(f, ", '")?;
852 fmt_utf8_bytes_simple(f, param)?;
853 write!(f, "'")?;
854 }
855 write!(f, ", {:?}", self.intermediates)?;
856 write!(f, ", {:?})", self.final_byte as char)?;
857 Ok(())
858 }
859}
860
861#[cfg_attr(feature = "serde", derive(serde::Serialize))]
862#[derive(Clone, PartialEq, Eq)]
863pub struct DCSOwned {
864 pub private: Option<u8>,
865 pub params: ParamBufOwned,
866 pub intermediates: VTIntermediate,
867 pub final_byte: u8,
868}
869
870impl std::fmt::Debug for DCSOwned {
871 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
872 write!(f, "DcsStart(")?;
873 if let Some(p) = self.private {
874 write!(f, "{:?}", p as char)?;
875 }
876 for param in &self.params {
877 write!(f, ", '")?;
878 fmt_utf8_bytes_simple(f, param)?;
879 write!(f, "'")?;
880 }
881 write!(f, ", {:?}", self.intermediates)?;
882 write!(f, ", {})", self.final_byte as char)?;
883 Ok(())
884 }
885}
886
887#[cfg(test)]
888mod test {
889 use super::*;
890
891 #[test]
892 fn test_numeric_param_buf() {
893 let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
894 let numeric_param_buf = param_buf.numeric();
895 assert_eq!(
896 numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
897 vec![Some(1), Some(2), Some(3), Some(4), None, None]
898 );
899 }
900}