1use std::iter::Map;
2
3use smallvec::SmallVec;
4
5use crate::AsciiControl;
6
7fn fmt_utf8_bytes_with_ascii_control(
9 f: &mut std::fmt::Formatter<'_>,
10 bytes: &[u8],
11) -> std::fmt::Result {
12 for chunk in bytes.utf8_chunks() {
13 for c in chunk.valid().chars() {
14 if let Ok(c) = AsciiControl::try_from(c) {
15 write!(f, "{}", c)?;
16 } else {
17 write!(f, "{}", c)?;
18 }
19 }
20 if !chunk.invalid().is_empty() {
21 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
22 }
23 }
24 Ok(())
25}
26
27fn fmt_utf8_bytes_simple(f: &mut std::fmt::Formatter<'_>, bytes: &[u8]) -> std::fmt::Result {
29 for chunk in bytes.utf8_chunks() {
30 write!(f, "{}", chunk.valid())?;
31 if !chunk.invalid().is_empty() {
32 write!(f, "<{}>", hex::encode(chunk.invalid()))?;
33 }
34 }
35 Ok(())
36}
37
38#[cfg_attr(feature = "serde", derive(serde::Serialize))]
39#[derive(Default, Clone, Copy, PartialEq, Eq)]
40pub struct VTIntermediate {
41 pub(crate) data: [u8; 2],
42}
43
44impl VTIntermediate {
45 pub const fn empty() -> Self {
46 Self { data: [0, 0] }
47 }
48
49 pub const fn one(c: u8) -> Self {
50 assert!(c >= 0x20 && c <= 0x2F);
51 Self { data: [c, 0] }
52 }
53
54 pub const fn two(c1: u8, c2: u8) -> Self {
55 assert!(c1 >= 0x20 && c1 <= 0x2F);
56 assert!(c2 >= 0x20 && c2 <= 0x2F);
57 Self { data: [c1, c2] }
58 }
59
60 pub fn has(&self, c: u8) -> bool {
61 self.data[0] == c || self.data[1] == c
62 }
63
64 pub fn clear(&mut self) {
65 self.data[0] = 0;
66 self.data[1] = 0;
67 }
68
69 pub fn is_empty(&self) -> bool {
70 self.data[0] == 0 && self.data[1] == 0
71 }
72
73 pub fn len(&self) -> usize {
74 self.data.iter().filter(|&&c| c != 0).count()
75 }
76
77 pub fn first(&self) -> Option<u8> {
78 if self.data[0] != 0 {
79 Some(self.data[0])
80 } else {
81 None
82 }
83 }
84
85 pub fn second(&self) -> Option<u8> {
86 if self.data[1] != 0 {
87 Some(self.data[1])
88 } else {
89 None
90 }
91 }
92
93 #[must_use]
94 pub fn push(&mut self, c: u8) -> bool {
95 if c < 0x20 || c > 0x2F {
96 return false;
97 }
98
99 if self.data[0] == c {
101 return false;
102 }
103
104 if self.data[0] == 0 {
105 self.data[0] = c;
106 true
107 } else if self.data[1] == 0 {
108 self.data[1] = c;
109 true
110 } else {
111 false
112 }
113 }
114
115 pub const fn const_eq(&self, other: &Self) -> bool {
116 self.data[0] == other.data[0] && self.data[1] == other.data[1]
117 }
118
119 pub fn byte_len(&self) -> usize {
120 self.data.iter().filter(|&&c| c != 0).count()
121 }
122}
123
124impl std::fmt::Debug for VTIntermediate {
125 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
126 write!(f, "'")?;
128 for c in self.data.iter() {
129 if *c == 0 {
130 break;
131 }
132 write!(f, "{}", *c as char)?;
133 }
134 write!(f, "'")?;
135 Ok(())
136 }
137}
138
139pub(crate) type Param = SmallVec<[u8; 32]>;
140pub(crate) type Params = SmallVec<[Param; 8]>;
141
142#[cfg_attr(feature = "serde", derive(serde::Serialize))]
143#[derive(Debug, Copy, Clone, PartialEq, Eq)]
144#[repr(transparent)]
145pub struct ParamBuf<'a> {
146 pub(crate) params: &'a Params,
147}
148
149impl<'a> IntoIterator for ParamBuf<'a> {
150 type Item = &'a [u8];
151 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
152 fn into_iter(self) -> Self::IntoIter {
153 self.params.iter().map(|p| p.as_slice())
154 }
155}
156
157impl<'b, 'a> IntoIterator for &'b ParamBuf<'a> {
158 type Item = &'a [u8];
159 type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
160 fn into_iter(self) -> Self::IntoIter {
161 self.params.iter().map(|p| p.as_slice())
162 }
163}
164
165impl<'a> ParamBuf<'a> {
166 pub fn len(&self) -> usize {
167 self.params.len()
168 }
169
170 pub fn is_empty(&self) -> bool {
171 self.params.is_empty()
172 }
173
174 pub fn get(&self, index: usize) -> Option<&[u8]> {
175 self.params.get(index).map(|p| p.as_slice())
176 }
177
178 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
179 self.params.get(index).and_then(|p| {
180 std::str::from_utf8(p.as_slice())
181 .ok()
182 .and_then(|s| s.parse::<T>().ok())
183 })
184 }
185
186 pub fn to_owned(&self) -> ParamBufOwned {
187 ParamBufOwned {
188 params: self.params.iter().map(|p| p.clone()).collect(),
189 }
190 }
191
192 pub fn byte_len(&self) -> usize {
193 self.params.iter().map(|p| p.len()).sum::<usize>() + self.params.len().saturating_sub(1)
194 }
195}
196
197#[cfg_attr(feature = "serde", derive(serde::Serialize))]
198#[derive(Clone, PartialEq, Eq)]
199pub enum VTEvent<'a> {
200 Raw(&'a [u8]),
202
203 C0(u8),
205
206 Esc(Esc),
208
209 EscInvalid(EscInvalid),
211
212 Ss2(SS2),
214
215 Ss3(SS3),
217
218 Csi(CSI<'a>),
220
221 DcsStart(DCS<'a>),
223 DcsData(&'a [u8]),
224 DcsEnd(&'a [u8]),
225 DcsCancel,
226
227 OscStart,
229 OscData(&'a [u8]),
230 OscEnd {
231 data: &'a [u8],
232 used_bel: bool,
234 },
235 OscCancel,
236}
237
238impl<'a> std::fmt::Debug for VTEvent<'a> {
239 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240 use VTEvent::*;
241 match self {
242 Raw(s) => {
243 write!(f, "Raw('")?;
244 fmt_utf8_bytes_with_ascii_control(f, s)?;
245 write!(f, "')")?;
246 Ok(())
247 }
248 EscInvalid(esc_invalid) => esc_invalid.fmt(f),
249 C0(b) => write!(f, "C0({:02x})", b),
250 Esc(esc) => esc.fmt(f),
251 Ss2(ss2) => ss2.fmt(f),
252 Ss3(ss3) => ss3.fmt(f),
253 Csi(csi) => csi.fmt(f),
254 DcsStart(dcs_start) => dcs_start.fmt(f),
255 DcsData(s) | DcsEnd(s) => {
256 if matches!(self, DcsEnd(..)) {
257 write!(f, "DcsEnd('")?;
258 } else {
259 write!(f, "DcsData('")?;
260 }
261 fmt_utf8_bytes_with_ascii_control(f, s)?;
262 write!(f, "')")?;
263 Ok(())
264 }
265 DcsCancel => write!(f, "DcsCancel"),
266 OscStart => write!(f, "OscStart"),
267 OscData(s) | OscEnd { data: s, .. } => {
268 if matches!(self, OscEnd { .. }) {
269 write!(f, "OscEnd('")?;
270 } else {
271 write!(f, "OscData('")?;
272 }
273 fmt_utf8_bytes_with_ascii_control(f, s)?;
274 write!(f, "')")?;
275 Ok(())
276 }
277 OscCancel => write!(f, "OscCancel"),
278 }
279 }
280}
281
282impl<'a> VTEvent<'a> {
283 pub fn csi(&self) -> Option<CSI> {
284 match self {
285 VTEvent::Csi(csi) => Some(CSI {
286 private: csi.private,
287 params: csi.params,
288 intermediates: csi.intermediates.clone(),
289 final_byte: csi.final_byte,
290 }),
291 _ => None,
292 }
293 }
294
295 pub fn byte_len(&self) -> usize {
296 use VTEvent::*;
297 let len = match self {
298 Raw(s) => s.len(),
299 C0(_) => 1,
300 Esc(esc) => esc.intermediates.len() + 2,
301 EscInvalid(esc_invalid) => {
302 use self::EscInvalid::*;
303 match esc_invalid {
304 One(..) => 2,
305 Two(..) => 3,
306 Three(..) => 4,
307 }
308 }
309 Ss2(_) => 3,
310 Ss3(_) => 3,
311 Csi(csi) => {
312 csi.private.is_some() as usize
313 + csi.params.byte_len()
314 + csi.intermediates.byte_len()
315 + 3
316 }
317 DcsStart(dcs_start) => {
318 dcs_start.private.is_some() as usize
319 + dcs_start.params.byte_len()
320 + dcs_start.intermediates.byte_len()
321 + 3
322 }
323 DcsData(s) => s.len(),
324 DcsEnd(s) => s.len() + 2,
325 DcsCancel => 1,
326 OscStart => 2,
327 OscData(s) => s.len(),
328 OscEnd { data, used_bel } => {
329 if *used_bel {
330 data.len() + 1
331 } else {
332 data.len() + 2
333 }
334 }
335 OscCancel => 1,
336 };
337 len
338 }
339
340 pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
346 use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
347 use VTEvent::*;
348
349 let len = self.byte_len();
350
351 if len > buf.len() {
352 return Err(len);
353 }
354
355 match self {
356 Raw(s) | OscData(s) | DcsData(s) => {
357 buf[..s.len()].copy_from_slice(s);
358 }
359 EscInvalid(esc_invalid) => {
360 use self::EscInvalid::*;
361 buf[0] = ESC;
362 match esc_invalid {
363 One(b) => buf[1] = *b,
364 Two(b1, b2) => {
365 buf[1] = *b1;
366 buf[2] = *b2;
367 }
368 Three(b1, b2, b3) => {
369 buf[1] = *b1;
370 buf[2] = *b2;
371 buf[3] = *b3;
372 }
373 }
374 }
375 OscCancel | DcsCancel => {
376 buf[0] = CAN;
377 }
378 C0(b) => {
379 buf[0] = *b;
380 }
381 Ss2(ss2) => {
382 buf[0] = ESC;
383 buf[1] = SS2;
384 buf[2] = ss2.char;
385 }
386 Ss3(ss3) => {
387 buf[0] = ESC;
388 buf[1] = SS3;
389 buf[2] = ss3.char;
390 }
391 Esc(esc) => {
392 buf[0] = ESC;
393 buf[1..esc.intermediates.len() + 1]
394 .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
395 buf[esc.intermediates.len() + 1] = esc.final_byte;
396 }
397 Csi(csi) => {
398 buf[0] = ESC;
399 buf[1] = CSI;
400 buf = &mut buf[2..];
401 if let Some(p) = csi.private {
402 buf[0] = p;
403 buf = &mut buf[1..];
404 }
405 let mut params = csi.params.into_iter();
406 if let Some(param) = params.next() {
407 buf[..param.len()].copy_from_slice(param);
408 buf = &mut buf[param.len()..];
409 for param in params {
410 buf[0] = b';';
411 buf = &mut buf[1..];
412 buf[..param.len()].copy_from_slice(param);
413 buf = &mut buf[param.len()..];
414 }
415 }
416 buf[..csi.intermediates.len()]
417 .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
418 buf[csi.intermediates.len()] = csi.final_byte;
419 }
420 DcsStart(dcs_start) => {
421 buf[0] = ESC;
422 buf[1] = DCS;
423 buf = &mut buf[2..];
424 if let Some(p) = dcs_start.private {
425 buf[0] = p;
426 buf = &mut buf[1..];
427 }
428 let mut params = dcs_start.params.into_iter();
429 if let Some(param) = params.next() {
430 buf[..param.len()].copy_from_slice(param);
431 buf = &mut buf[param.len()..];
432 for param in params {
433 buf[0] = b';';
434 buf = &mut buf[1..];
435 buf[..param.len()].copy_from_slice(param);
436 buf = &mut buf[param.len()..];
437 }
438 }
439 buf[..dcs_start.intermediates.len()].copy_from_slice(
440 &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
441 );
442 buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
443 }
444 DcsEnd(data) => {
445 buf[..data.len()].copy_from_slice(data);
446 buf = &mut buf[data.len()..];
447 buf[0] = ESC;
448 buf[1] = ST_FINAL;
449 }
450 OscStart => {
451 buf[0] = ESC;
452 buf[1] = OSC;
453 }
454 OscEnd { data, used_bel } => {
455 buf[..data.len()].copy_from_slice(data);
456 buf = &mut buf[data.len()..];
457 if *used_bel {
458 buf[0] = BEL;
459 } else {
460 buf[0] = ESC;
461 buf[1] = ST_FINAL
462 }
463 }
464 }
465
466 Ok(len)
467 }
468
469 pub fn to_owned(&self) -> VTOwnedEvent {
470 use VTEvent::*;
471 match self {
472 Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
473 C0(b) => VTOwnedEvent::C0(*b),
474 Esc(esc) => VTOwnedEvent::Esc(*esc),
475 EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
476 Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
477 Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
478 Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
479 private: csi.private,
480 params: csi.params.to_owned(),
481 intermediates: csi.intermediates.clone(),
482 final_byte: csi.final_byte,
483 }),
484 DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
485 private: dcs_start.private,
486 params: dcs_start.params.to_owned(),
487 intermediates: dcs_start.intermediates.clone(),
488 final_byte: dcs_start.final_byte,
489 }),
490 DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
491 DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
492 DcsCancel => VTOwnedEvent::DcsCancel,
493 OscStart => VTOwnedEvent::OscStart,
494 OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
495 OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
496 data: data.to_vec(),
497 used_bel: *used_bel,
498 },
499 OscCancel => VTOwnedEvent::OscCancel,
500 }
501 }
502}
503
504#[cfg_attr(feature = "serde", derive(serde::Serialize))]
505#[derive(Clone, PartialEq, Eq, Debug)]
506pub struct ParamBufOwned {
507 pub(crate) params: Params,
508}
509
510impl IntoIterator for ParamBufOwned {
511 type Item = Param;
512 type IntoIter = <Params as IntoIterator>::IntoIter;
513 fn into_iter(self) -> Self::IntoIter {
514 self.params.into_iter()
515 }
516}
517
518impl<'b> IntoIterator for &'b ParamBufOwned {
519 type Item = &'b [u8];
520 type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
521 fn into_iter(self) -> Self::IntoIter {
522 self.params.iter().map(|p| p.as_slice())
523 }
524}
525
526impl ParamBufOwned {
527 pub fn len(&self) -> usize {
528 self.params.len()
529 }
530
531 pub fn is_empty(&self) -> bool {
532 self.params.is_empty()
533 }
534
535 pub fn get(&self, index: usize) -> Option<&[u8]> {
536 self.params.get(index).map(|p| p.as_slice())
537 }
538
539 pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
540 self.params.get(index).and_then(|p| {
541 std::str::from_utf8(p.as_slice())
542 .ok()
543 .and_then(|s| s.parse::<T>().ok())
544 })
545 }
546
547 pub fn borrow(&self) -> ParamBuf<'_> {
548 ParamBuf {
549 params: &self.params,
550 }
551 }
552}
553
554#[cfg_attr(feature = "serde", derive(serde::Serialize))]
555#[derive(Clone, PartialEq, Eq)]
556pub enum VTOwnedEvent {
557 Raw(Vec<u8>),
558 C0(u8),
559 Esc(Esc),
560 EscInvalid(EscInvalid),
561 Ss2(SS2),
562 Ss3(SS3),
563 Csi(CSIOwned),
564 DcsStart(DCSOwned),
565 DcsData(Vec<u8>),
566 DcsEnd(Vec<u8>),
567 DcsCancel,
568 OscStart,
569 OscData(Vec<u8>),
570 OscEnd { data: Vec<u8>, used_bel: bool },
571 OscCancel,
572}
573
574impl std::fmt::Debug for VTOwnedEvent {
575 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
576 self.borrow().fmt(f)
577 }
578}
579
580impl VTOwnedEvent {
581 pub fn borrow(&self) -> VTEvent<'_> {
582 match self {
583 VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
584 VTOwnedEvent::C0(b) => VTEvent::C0(*b),
585 VTOwnedEvent::Esc(esc) => VTEvent::Esc(Esc {
586 intermediates: esc.intermediates.clone(),
587 final_byte: esc.final_byte,
588 }),
589 VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
590 VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
591 VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
592 VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
593 private: csi.private,
594 params: csi.params.borrow(),
595 intermediates: csi.intermediates,
596 final_byte: csi.final_byte,
597 }),
598 VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
599 private: dcs_start.private,
600 params: dcs_start.params.borrow(),
601 intermediates: dcs_start.intermediates.clone(),
602 final_byte: dcs_start.final_byte,
603 }),
604 VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
605 VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
606 VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
607 VTOwnedEvent::OscStart => VTEvent::OscStart,
608 VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
609 VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
610 data: data,
611 used_bel: *used_bel,
612 },
613 VTOwnedEvent::OscCancel => VTEvent::OscCancel,
614 }
615 }
616}
617
618#[cfg_attr(feature = "serde", derive(serde::Serialize))]
620#[derive(Clone, Copy, PartialEq, Eq)]
621pub enum EscInvalid {
622 One(u8),
623 Two(u8, u8),
624 Three(u8, u8, u8),
625}
626
627impl std::fmt::Debug for EscInvalid {
628 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
629 match self {
630 EscInvalid::One(b) => write!(f, "EscInvalid({:?})", b)?,
631 EscInvalid::Two(b1, b2) => write!(f, "EscInvalid({:?}, {:?})", b1, b2)?,
632 EscInvalid::Three(b1, b2, b3) => write!(f, "EscInvalid({:?}, {:?}, {:?})", b1, b2, b3)?,
633 }
634 Ok(())
635 }
636}
637
638#[cfg_attr(feature = "serde", derive(serde::Serialize))]
639#[derive(Clone, Copy, PartialEq, Eq)]
640pub struct Esc {
641 pub intermediates: VTIntermediate,
642 pub final_byte: u8,
643}
644
645impl std::fmt::Debug for Esc {
646 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
647 write!(f, "Esc({:?}", self.intermediates)?;
648 write!(f, ", ")?;
649 if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
650 write!(f, "{})", c)?;
651 } else {
652 write!(f, "{})", self.final_byte as char)?;
653 }
654 Ok(())
655 }
656}
657
658#[cfg_attr(feature = "serde", derive(serde::Serialize))]
659#[derive(Clone, Copy, PartialEq, Eq)]
660pub struct SS2 {
661 pub char: u8,
662}
663
664impl std::fmt::Debug for SS2 {
665 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
666 write!(f, "Ss2(")?;
667 if let Ok(c) = AsciiControl::try_from(self.char as char) {
668 write!(f, "{})", c)?;
669 } else {
670 write!(f, "{:?})", self.char as char)?;
671 }
672 Ok(())
673 }
674}
675
676#[cfg_attr(feature = "serde", derive(serde::Serialize))]
677#[derive(Clone, Copy, PartialEq, Eq)]
678pub struct SS3 {
679 pub char: u8,
680}
681
682impl std::fmt::Debug for SS3 {
683 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
684 write!(f, "Ss3(")?;
685 if let Ok(c) = AsciiControl::try_from(self.char as char) {
686 write!(f, "{})", c)?;
687 } else {
688 write!(f, "{:?})", self.char as char)?;
689 }
690 Ok(())
691 }
692}
693
694#[cfg_attr(feature = "serde", derive(serde::Serialize))]
695#[derive(Clone, PartialEq, Eq)]
696pub struct CSI<'a> {
697 pub private: Option<u8>,
698 pub params: ParamBuf<'a>,
699 pub intermediates: VTIntermediate,
700 pub final_byte: u8,
701}
702
703impl<'a> std::fmt::Debug for CSI<'a> {
704 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
705 write!(f, "Csi(")?;
706 if let Some(p) = self.private {
707 write!(f, "{:?}", p as char)?;
708 }
709 for param in &self.params {
710 write!(f, ", '")?;
711 fmt_utf8_bytes_simple(f, param)?;
712 write!(f, "'")?;
713 }
714 write!(f, ", {:?}", self.intermediates)?;
715 write!(f, ", {:?})", self.final_byte as char)?;
716 Ok(())
717 }
718}
719
720#[cfg_attr(feature = "serde", derive(serde::Serialize))]
721#[derive(Clone, PartialEq, Eq)]
722pub struct DCS<'a> {
723 pub private: Option<u8>,
724 pub params: ParamBuf<'a>,
725 pub intermediates: VTIntermediate,
726 pub final_byte: u8,
727}
728
729impl<'a> std::fmt::Debug for DCS<'a> {
730 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
731 write!(f, "DcsStart(")?;
732 if let Some(p) = self.private {
733 write!(f, "{:?}", p as char)?;
734 }
735 for param in &self.params {
736 write!(f, ", '")?;
737 fmt_utf8_bytes_simple(f, param)?;
738 write!(f, "'")?;
739 }
740 write!(f, ", {:?}", self.intermediates)?;
741 write!(f, ", {})", self.final_byte as char)?;
742 Ok(())
743 }
744}
745
746#[cfg_attr(feature = "serde", derive(serde::Serialize))]
747#[derive(Clone, PartialEq, Eq)]
748pub struct CSIOwned {
749 pub private: Option<u8>,
750 pub params: ParamBufOwned,
751 pub intermediates: VTIntermediate,
752 pub final_byte: u8,
753}
754
755impl std::fmt::Debug for CSIOwned {
756 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
757 write!(f, "Csi(")?;
758 if let Some(p) = self.private {
759 write!(f, "{:?}", p as char)?;
760 }
761 for param in &self.params {
762 write!(f, ", '")?;
763 fmt_utf8_bytes_simple(f, param)?;
764 write!(f, "'")?;
765 }
766 write!(f, ", {:?}", self.intermediates)?;
767 write!(f, ", {:?})", self.final_byte as char)?;
768 Ok(())
769 }
770}
771
772#[cfg_attr(feature = "serde", derive(serde::Serialize))]
773#[derive(Clone, PartialEq, Eq)]
774pub struct DCSOwned {
775 pub private: Option<u8>,
776 pub params: ParamBufOwned,
777 pub intermediates: VTIntermediate,
778 pub final_byte: u8,
779}
780
781impl std::fmt::Debug for DCSOwned {
782 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
783 write!(f, "DcsStart(")?;
784 if let Some(p) = self.private {
785 write!(f, "{:?}", p as char)?;
786 }
787 for param in &self.params {
788 write!(f, ", '")?;
789 fmt_utf8_bytes_simple(f, param)?;
790 write!(f, "'")?;
791 }
792 write!(f, ", {:?}", self.intermediates)?;
793 write!(f, ", {})", self.final_byte as char)?;
794 Ok(())
795 }
796}