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