vt_push_parser/
event.rs

1//! Event types.
2use std::iter::Map;
3
4use smallvec::SmallVec;
5
6use crate::AsciiControl;
7
8/// Helper function to format UTF-8 chunks with ASCII control character handling
9fn 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
28/// Helper function to format UTF-8 chunks for parameters (simple formatting)
29fn 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, Hash)]
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        // Invalid duplicate intermediate
101        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 AsRef<[u8]> for VTIntermediate {
126    fn as_ref(&self) -> &[u8] {
127        &self.data[..self.byte_len()]
128    }
129}
130
131impl std::fmt::Debug for VTIntermediate {
132    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
133        // Inefficient
134        write!(f, "'")?;
135        for c in self.data.iter() {
136            if *c == 0 {
137                break;
138            }
139            write!(f, "{}", *c as char)?;
140        }
141        write!(f, "'")?;
142        Ok(())
143    }
144}
145
146pub(crate) type Param = SmallVec<[u8; 32]>;
147pub(crate) type Params = SmallVec<[Param; 8]>;
148
149static EMPTY_PARAMS: Params = Params::new_const();
150
151#[cfg_attr(feature = "serde", derive(serde::Serialize))]
152#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
153#[repr(transparent)]
154pub struct ParamBuf<'a> {
155    pub(crate) params: &'a Params,
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> IntoIterator for &ParamBuf<'a> {
167    type Item = &'a [u8];
168    type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&Param) -> &[u8]>;
169    fn into_iter(self) -> Self::IntoIter {
170        self.params.iter().map(|p| p.as_slice())
171    }
172}
173
174impl<'a> ParamBuf<'a> {
175    pub const fn empty() -> Self {
176        ParamBuf {
177            params: &EMPTY_PARAMS,
178        }
179    }
180
181    pub fn len(&self) -> usize {
182        self.params.len()
183    }
184
185    pub fn is_empty(&self) -> bool {
186        self.params.is_empty()
187    }
188
189    pub fn get(&self, index: usize) -> Option<&[u8]> {
190        self.params.get(index).map(|p| p.as_slice())
191    }
192
193    pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
194        self.params.get(index).and_then(|p| {
195            std::str::from_utf8(p.as_slice())
196                .ok()
197                .and_then(|s| s.parse::<T>().ok())
198        })
199    }
200
201    pub fn to_owned(&self) -> ParamBufOwned {
202        ParamBufOwned {
203            params: self.params.iter().cloned().collect(),
204        }
205    }
206
207    pub fn byte_len(&self) -> usize {
208        self.params.iter().map(|p| p.len()).sum::<usize>() + self.params.len().saturating_sub(1)
209    }
210
211    pub fn numeric(&self) -> NumericParamBuf<'a> {
212        NumericParamBuf {
213            params: self.params,
214        }
215    }
216}
217
218/// A view into a [`Param`] that contains only numeric parameters.
219#[derive(Debug, Copy, Clone, Default)]
220pub struct NumericParam<'a> {
221    pub(crate) param: &'a [u8],
222}
223
224impl<'a> NumericParam<'a> {
225    /// Try to parse the parameter as a single numeric value.
226    pub fn sole(&self) -> Option<u16> {
227        if !self.param.is_empty() && !self.param.contains(&b':') {
228            if let Ok(s) = std::str::from_utf8(self.param) {
229                s.parse::<u16>().ok()
230            } else {
231                None
232            }
233        } else {
234            None
235        }
236    }
237
238    /// Try to parse the first parameter as a single numeric value.
239    pub fn first(&self) -> Option<u16> {
240        self.into_iter().next().flatten()
241    }
242
243    pub fn is_empty(&self) -> bool {
244        self.param.is_empty()
245    }
246
247    pub fn len(&self) -> usize {
248        self.param.iter().filter(|p| **p == b':').count() + 1
249    }
250
251    /// Try to write the parameters to the given buffer, returning the written
252    /// slice if successful. If any parameters are not a single-numeric value,
253    /// writes a zero in that position.
254    ///
255    /// If the slice is not long enough, returns an error with the required
256    /// length.
257    pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
258        let len = self.len();
259        if buf.len() < len {
260            return Err(buf.len());
261        }
262        for (i, param) in self.into_iter().enumerate() {
263            buf[i] = param.unwrap_or(0);
264        }
265        Ok(&buf[..len])
266    }
267}
268
269impl<'a> IntoIterator for NumericParam<'a> {
270    type Item = Option<u16>;
271    type IntoIter = Map<std::slice::Split<'a, u8, fn(&u8) -> bool>, fn(&'a [u8]) -> Option<u16>>;
272    fn into_iter(self) -> Self::IntoIter {
273        let fn1: fn(&u8) -> bool = |c: &u8| *c == b':';
274        self.param.split(fn1).map(|p| {
275            if p.is_empty() {
276                None
277            } else {
278                std::str::from_utf8(p)
279                    .ok()
280                    .and_then(|s| s.parse::<u16>().ok())
281            }
282        })
283    }
284}
285
286/// A view into a [`ParamBuf`] that contains only numeric parameters.
287///
288/// Each parameter may contain zero or more numeric values, separated by colons.
289/// Empty parameters are interpreted as `None`.
290#[derive(Debug, Copy, Clone)]
291pub struct NumericParamBuf<'a> {
292    pub(crate) params: &'a Params,
293}
294
295impl<'a> IntoIterator for NumericParamBuf<'a> {
296    type Item = NumericParam<'a>;
297    type IntoIter = Map<std::slice::Iter<'a, Param>, fn(&'a Param) -> NumericParam<'a>>;
298    fn into_iter(self) -> Self::IntoIter {
299        self.params.iter().map(|p| NumericParam {
300            param: p.as_slice(),
301        })
302    }
303}
304
305impl<'a> NumericParamBuf<'a> {
306    pub const fn empty() -> Self {
307        NumericParamBuf {
308            params: &EMPTY_PARAMS,
309        }
310    }
311
312    /// Try to write the parameters to the given buffer, returning the written
313    /// slice if successful. If any parameters are not a single-numeric value,
314    /// writes a zero in that position.
315    ///
316    /// If the slice is not long enough, returns an error with the required
317    /// length.
318    pub fn try_write<'b>(&self, buf: &'b mut [u16]) -> Result<&'b [u16], usize> {
319        let len = self.params.len();
320        if buf.len() < len {
321            return Err(buf.len());
322        }
323        for (i, param) in self.into_iter().enumerate() {
324            buf[i] = param.sole().unwrap_or(0);
325        }
326        Ok(&buf[..len])
327    }
328
329    pub fn get(&self, index: usize) -> Option<NumericParam<'a>> {
330        self.params.get(index).map(|p| NumericParam {
331            param: p.as_slice(),
332        })
333    }
334
335    pub fn first(&self) -> Option<NumericParam<'a>> {
336        self.into_iter().next()
337    }
338
339    pub fn is_empty(&self) -> bool {
340        self.params.is_empty()
341    }
342
343    pub fn len(&self) -> usize {
344        self.params.len()
345    }
346}
347
348/// A union of all possible events that can be emitted by the parser, with
349/// borrowed data.
350#[cfg_attr(feature = "serde", derive(serde::Serialize))]
351#[derive(Clone, PartialEq, Eq, Hash)]
352pub enum VTEvent<'a> {
353    // Plain printable text from GROUND (coalesced)
354    Raw(&'a [u8]),
355
356    // C0 control (EXECUTE)
357    C0(u8),
358
359    // ESC final (with intermediates)
360    Esc(Esc),
361
362    // Invalid escape sequence
363    EscInvalid(EscInvalid),
364
365    // SS2
366    Ss2(SS2),
367
368    // SS3
369    Ss3(SS3),
370
371    // CSI short escape
372    Csi(CSI<'a>),
373
374    // DCS stream
375    DcsStart(DCS<'a>),
376    DcsData(&'a [u8]),
377    DcsEnd(&'a [u8]),
378    DcsCancel,
379
380    // OSC stream
381    OscStart,
382    OscData(&'a [u8]),
383    OscEnd {
384        data: &'a [u8],
385        /// Whether the BEL was used to end the OSC stream.
386        used_bel: bool,
387    },
388    OscCancel,
389}
390
391impl<'a> std::fmt::Debug for VTEvent<'a> {
392    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
393        use VTEvent::*;
394        match self {
395            Raw(s) => {
396                write!(f, "Raw('")?;
397                fmt_utf8_bytes_with_ascii_control(f, s)?;
398                write!(f, "')")?;
399                Ok(())
400            }
401            EscInvalid(esc_invalid) => esc_invalid.fmt(f),
402            C0(b) => write!(f, "C0({b:02x})"),
403            Esc(esc) => esc.fmt(f),
404            Ss2(ss2) => ss2.fmt(f),
405            Ss3(ss3) => ss3.fmt(f),
406            Csi(csi) => csi.fmt(f),
407            DcsStart(dcs_start) => dcs_start.fmt(f),
408            DcsData(s) | DcsEnd(s) => {
409                if matches!(self, DcsEnd(..)) {
410                    write!(f, "DcsEnd('")?;
411                } else {
412                    write!(f, "DcsData('")?;
413                }
414                fmt_utf8_bytes_with_ascii_control(f, s)?;
415                write!(f, "')")?;
416                Ok(())
417            }
418            DcsCancel => write!(f, "DcsCancel"),
419            OscStart => write!(f, "OscStart"),
420            OscData(s) | OscEnd { data: s, .. } => {
421                if matches!(self, OscEnd { .. }) {
422                    write!(f, "OscEnd('")?;
423                } else {
424                    write!(f, "OscData('")?;
425                }
426                fmt_utf8_bytes_with_ascii_control(f, s)?;
427                write!(f, "')")?;
428                Ok(())
429            }
430            OscCancel => write!(f, "OscCancel"),
431        }
432    }
433}
434
435impl<'a> VTEvent<'a> {
436    pub fn csi(&self) -> Option<CSI> {
437        match self {
438            VTEvent::Csi(csi) => Some(CSI {
439                private: csi.private,
440                params: csi.params,
441                intermediates: csi.intermediates,
442                final_byte: csi.final_byte,
443            }),
444            _ => None,
445        }
446    }
447
448    pub fn byte_len(&self) -> usize {
449        use VTEvent::*;
450
451        match self {
452            Raw(s) => s.len(),
453            C0(_) => 1,
454            Esc(esc) => esc.intermediates.len() + 2 + esc.private.is_some() as usize,
455            EscInvalid(esc_invalid) => {
456                use self::EscInvalid::*;
457                match esc_invalid {
458                    One(..) => 2,
459                    Two(..) => 3,
460                    Three(..) => 4,
461                    Four(..) => 5,
462                }
463            }
464            Ss2(_) => 3,
465            Ss3(_) => 3,
466            Csi(csi) => {
467                csi.private.is_some() as usize
468                    + csi.params.byte_len()
469                    + csi.intermediates.byte_len()
470                    + 3
471            }
472            DcsStart(dcs_start) => {
473                dcs_start.private.is_some() as usize
474                    + dcs_start.params.byte_len()
475                    + dcs_start.intermediates.byte_len()
476                    + 3
477            }
478            DcsData(s) => s.len(),
479            DcsEnd(s) => s.len() + 2,
480            DcsCancel => 1,
481            OscStart => 2,
482            OscData(s) => s.len(),
483            OscEnd { data, used_bel } => {
484                if *used_bel {
485                    data.len() + 1
486                } else {
487                    data.len() + 2
488                }
489            }
490            OscCancel => 1,
491        }
492    }
493
494    /// Encode the event into the provided buffer, returning the number of bytes
495    /// required for the escape sequence in either `Ok(n)` or `Err(n)`.
496    ///
497    /// Note that some events may have multiple possible encodings, so this method
498    /// may decide to choose whichever is more efficient.
499    pub fn encode(&self, mut buf: &mut [u8]) -> Result<usize, usize> {
500        use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
501        use VTEvent::*;
502
503        let len = self.byte_len();
504
505        if len > buf.len() {
506            return Err(len);
507        }
508
509        match self {
510            Raw(s) | OscData(s) | DcsData(s) => {
511                buf[..s.len()].copy_from_slice(s);
512            }
513            EscInvalid(esc_invalid) => {
514                use self::EscInvalid::*;
515                buf[0] = ESC;
516                match esc_invalid {
517                    One(b) => buf[1] = *b,
518                    Two(b1, b2) => {
519                        buf[1] = *b1;
520                        buf[2] = *b2;
521                    }
522                    Three(b1, b2, b3) => {
523                        buf[1] = *b1;
524                        buf[2] = *b2;
525                        buf[3] = *b3;
526                    }
527                    Four(b1, b2, b3, b4) => {
528                        buf[1] = *b1;
529                        buf[2] = *b2;
530                        buf[3] = *b3;
531                        buf[4] = *b4;
532                    }
533                }
534            }
535            OscCancel | DcsCancel => {
536                buf[0] = CAN;
537            }
538            C0(b) => {
539                buf[0] = *b;
540            }
541            Ss2(ss2) => {
542                buf[0] = ESC;
543                buf[1] = SS2;
544                buf[2] = ss2.char;
545            }
546            Ss3(ss3) => {
547                buf[0] = ESC;
548                buf[1] = SS3;
549                buf[2] = ss3.char;
550            }
551            Esc(esc) => {
552                buf[0] = ESC;
553                if let Some(p) = esc.private {
554                    buf[1] = p;
555                    buf = &mut buf[1..];
556                }
557                buf[1..esc.intermediates.len() + 1]
558                    .copy_from_slice(&esc.intermediates.data[..esc.intermediates.len()]);
559                buf[esc.intermediates.len() + 1] = esc.final_byte;
560            }
561            Csi(csi) => {
562                buf[0] = ESC;
563                buf[1] = CSI;
564                buf = &mut buf[2..];
565                if let Some(p) = csi.private {
566                    buf[0] = p;
567                    buf = &mut buf[1..];
568                }
569                let mut params = csi.params.into_iter();
570                if let Some(param) = params.next() {
571                    buf[..param.len()].copy_from_slice(param);
572                    buf = &mut buf[param.len()..];
573                    for param in params {
574                        buf[0] = b';';
575                        buf = &mut buf[1..];
576                        buf[..param.len()].copy_from_slice(param);
577                        buf = &mut buf[param.len()..];
578                    }
579                }
580                buf[..csi.intermediates.len()]
581                    .copy_from_slice(&csi.intermediates.data[..csi.intermediates.len()]);
582                buf[csi.intermediates.len()] = csi.final_byte;
583            }
584            DcsStart(dcs_start) => {
585                buf[0] = ESC;
586                buf[1] = DCS;
587                buf = &mut buf[2..];
588                if let Some(p) = dcs_start.private {
589                    buf[0] = p;
590                    buf = &mut buf[1..];
591                }
592                let mut params = dcs_start.params.into_iter();
593                if let Some(param) = params.next() {
594                    buf[..param.len()].copy_from_slice(param);
595                    buf = &mut buf[param.len()..];
596                    for param in params {
597                        buf[0] = b';';
598                        buf = &mut buf[1..];
599                        buf[..param.len()].copy_from_slice(param);
600                        buf = &mut buf[param.len()..];
601                    }
602                }
603                buf[..dcs_start.intermediates.len()].copy_from_slice(
604                    &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
605                );
606                buf[dcs_start.intermediates.len()] = dcs_start.final_byte;
607            }
608            DcsEnd(data) => {
609                buf[..data.len()].copy_from_slice(data);
610                buf = &mut buf[data.len()..];
611                buf[0] = ESC;
612                buf[1] = ST_FINAL;
613            }
614            OscStart => {
615                buf[0] = ESC;
616                buf[1] = OSC;
617            }
618            OscEnd { data, used_bel } => {
619                buf[..data.len()].copy_from_slice(data);
620                buf = &mut buf[data.len()..];
621                if *used_bel {
622                    buf[0] = BEL;
623                } else {
624                    buf[0] = ESC;
625                    buf[1] = ST_FINAL
626                }
627            }
628        }
629
630        Ok(len)
631    }
632
633    pub fn to_owned(&self) -> VTOwnedEvent {
634        use VTEvent::*;
635        match self {
636            Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
637            C0(b) => VTOwnedEvent::C0(*b),
638            Esc(esc) => VTOwnedEvent::Esc(*esc),
639            EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
640            Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
641            Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
642            Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
643                private: csi.private,
644                params: csi.params.to_owned(),
645                intermediates: csi.intermediates,
646                final_byte: csi.final_byte,
647            }),
648            DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
649                private: dcs_start.private,
650                params: dcs_start.params.to_owned(),
651                intermediates: dcs_start.intermediates,
652                final_byte: dcs_start.final_byte,
653            }),
654            DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
655            DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
656            DcsCancel => VTOwnedEvent::DcsCancel,
657            OscStart => VTOwnedEvent::OscStart,
658            OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
659            OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
660                data: data.to_vec(),
661                used_bel: *used_bel,
662            },
663            OscCancel => VTOwnedEvent::OscCancel,
664        }
665    }
666}
667
668#[cfg_attr(feature = "serde", derive(serde::Serialize))]
669#[derive(Clone, PartialEq, Eq, Debug, Default)]
670pub struct ParamBufOwned {
671    pub(crate) params: Params,
672}
673
674impl IntoIterator for ParamBufOwned {
675    type Item = Param;
676    type IntoIter = <Params as IntoIterator>::IntoIter;
677    fn into_iter(self) -> Self::IntoIter {
678        self.params.into_iter()
679    }
680}
681
682impl<'b> IntoIterator for &'b ParamBufOwned {
683    type Item = &'b [u8];
684    type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
685    fn into_iter(self) -> Self::IntoIter {
686        self.params.iter().map(|p| p.as_slice())
687    }
688}
689
690impl ParamBufOwned {
691    /// Create an empty `ParamBufOwned`.
692    pub const fn empty() -> Self {
693        Self {
694            params: SmallVec::new_const(),
695        }
696    }
697
698    /// Create a `ParamBufOwned` from a slice of slices.
699    pub fn new(params: &[&[u8]]) -> Self {
700        Self {
701            params: params.iter().map(|p| Param::from(*p)).collect(),
702        }
703    }
704
705    pub fn len(&self) -> usize {
706        self.params.len()
707    }
708
709    pub fn is_empty(&self) -> bool {
710        self.params.is_empty()
711    }
712
713    pub fn get(&self, index: usize) -> Option<&[u8]> {
714        self.params.get(index).map(|p| p.as_slice())
715    }
716
717    pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
718        self.params.get(index).and_then(|p| {
719            std::str::from_utf8(p.as_slice())
720                .ok()
721                .and_then(|s| s.parse::<T>().ok())
722        })
723    }
724
725    pub fn borrow(&self) -> ParamBuf<'_> {
726        ParamBuf {
727            params: &self.params,
728        }
729    }
730
731    pub fn numeric(&self) -> NumericParamBuf<'_> {
732        NumericParamBuf {
733            params: &self.params,
734        }
735    }
736}
737
738/// A union of all possible events that can be emitted by the parser, with owned
739/// data.
740#[cfg_attr(feature = "serde", derive(serde::Serialize))]
741#[derive(Clone, PartialEq, Eq)]
742pub enum VTOwnedEvent {
743    Raw(Vec<u8>),
744    C0(u8),
745    Esc(Esc),
746    EscInvalid(EscInvalid),
747    Ss2(SS2),
748    Ss3(SS3),
749    Csi(CSIOwned),
750    DcsStart(DCSOwned),
751    DcsData(Vec<u8>),
752    DcsEnd(Vec<u8>),
753    DcsCancel,
754    OscStart,
755    OscData(Vec<u8>),
756    OscEnd { data: Vec<u8>, used_bel: bool },
757    OscCancel,
758}
759
760impl std::fmt::Debug for VTOwnedEvent {
761    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
762        self.borrow().fmt(f)
763    }
764}
765
766impl VTOwnedEvent {
767    pub fn borrow(&self) -> VTEvent<'_> {
768        match self {
769            VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
770            VTOwnedEvent::C0(b) => VTEvent::C0(*b),
771            VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
772            VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
773            VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
774            VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
775            VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
776                private: csi.private,
777                params: csi.params.borrow(),
778                intermediates: csi.intermediates,
779                final_byte: csi.final_byte,
780            }),
781            VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
782                private: dcs_start.private,
783                params: dcs_start.params.borrow(),
784                intermediates: dcs_start.intermediates,
785                final_byte: dcs_start.final_byte,
786            }),
787            VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
788            VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
789            VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
790            VTOwnedEvent::OscStart => VTEvent::OscStart,
791            VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
792            VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
793                data,
794                used_bel: *used_bel,
795            },
796            VTOwnedEvent::OscCancel => VTEvent::OscCancel,
797        }
798    }
799}
800
801/// An invalid escape sequence.
802#[cfg_attr(feature = "serde", derive(serde::Serialize))]
803#[derive(Clone, Copy, PartialEq, Eq, Hash)]
804pub enum EscInvalid {
805    One(u8),
806    Two(u8, u8),
807    Three(u8, u8, u8),
808    Four(u8, u8, u8, u8),
809}
810
811impl std::fmt::Debug for EscInvalid {
812    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
813        match self {
814            EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
815            EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
816            EscInvalid::Three(b1, b2, b3) => {
817                write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
818            }
819            EscInvalid::Four(b1, b2, b3, b4) => {
820                write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
821            }
822        }
823        Ok(())
824    }
825}
826
827#[cfg_attr(feature = "serde", derive(serde::Serialize))]
828#[derive(Clone, Copy, PartialEq, Eq, Hash)]
829pub struct Esc {
830    pub intermediates: VTIntermediate,
831    pub private: Option<u8>,
832    pub final_byte: u8,
833}
834
835impl std::fmt::Debug for Esc {
836    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
837        write!(f, "Esc(")?;
838        if let Some(p) = self.private {
839            write!(f, "{:?}, ", p as char)?;
840        }
841        write!(f, "{:?}, ", self.intermediates)?;
842        if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
843            write!(f, "{c})")?;
844        } else {
845            write!(f, "{})", self.final_byte as char)?;
846        }
847        Ok(())
848    }
849}
850
851#[cfg_attr(feature = "serde", derive(serde::Serialize))]
852#[derive(Clone, Copy, PartialEq, Eq, Hash)]
853pub struct SS2 {
854    pub char: u8,
855}
856
857impl std::fmt::Debug for SS2 {
858    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
859        write!(f, "Ss2(")?;
860        if let Ok(c) = AsciiControl::try_from(self.char as char) {
861            write!(f, "{c})")?;
862        } else {
863            write!(f, "{:?})", self.char as char)?;
864        }
865        Ok(())
866    }
867}
868
869#[cfg_attr(feature = "serde", derive(serde::Serialize))]
870#[derive(Clone, Copy, PartialEq, Eq, Hash)]
871pub struct SS3 {
872    pub char: u8,
873}
874
875impl std::fmt::Debug for SS3 {
876    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
877        write!(f, "Ss3(")?;
878        if let Ok(c) = AsciiControl::try_from(self.char as char) {
879            write!(f, "{c})")?;
880        } else {
881            write!(f, "{:?})", self.char as char)?;
882        }
883        Ok(())
884    }
885}
886
887#[cfg_attr(feature = "serde", derive(serde::Serialize))]
888#[derive(Clone, PartialEq, Eq, Hash)]
889pub struct CSI<'a> {
890    pub private: Option<u8>,
891    pub params: ParamBuf<'a>,
892    pub intermediates: VTIntermediate,
893    pub final_byte: u8,
894}
895
896impl<'a> std::fmt::Debug for CSI<'a> {
897    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
898        write!(f, "Csi(")?;
899        if let Some(p) = self.private {
900            write!(f, "{:?}, ", p as char)?;
901        }
902        for param in &self.params {
903            write!(f, "'")?;
904            fmt_utf8_bytes_simple(f, param)?;
905            write!(f, "', ")?;
906        }
907        write!(f, "{:?}, ", self.intermediates)?;
908        write!(f, "{:?})", self.final_byte as char)?;
909        Ok(())
910    }
911}
912
913#[cfg_attr(feature = "serde", derive(serde::Serialize))]
914#[derive(Clone, PartialEq, Eq, Hash)]
915pub struct DCS<'a> {
916    pub private: Option<u8>,
917    pub params: ParamBuf<'a>,
918    pub intermediates: VTIntermediate,
919    pub final_byte: u8,
920}
921
922impl<'a> std::fmt::Debug for DCS<'a> {
923    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
924        write!(f, "DcsStart(")?;
925        if let Some(p) = self.private {
926            write!(f, "{:?}, ", p as char)?;
927        }
928        for param in &self.params {
929            write!(f, "'")?;
930            fmt_utf8_bytes_simple(f, param)?;
931            write!(f, "', ")?;
932        }
933        write!(f, "{:?}, ", self.intermediates)?;
934        write!(f, "{})", self.final_byte as char)?;
935        Ok(())
936    }
937}
938
939#[cfg_attr(feature = "serde", derive(serde::Serialize))]
940#[derive(Clone, PartialEq, Eq)]
941pub struct CSIOwned {
942    pub private: Option<u8>,
943    pub params: ParamBufOwned,
944    pub intermediates: VTIntermediate,
945    pub final_byte: u8,
946}
947
948impl std::fmt::Debug for CSIOwned {
949    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
950        write!(f, "Csi(")?;
951        if let Some(p) = self.private {
952            write!(f, "{:?}", p as char)?;
953        }
954        for param in &self.params {
955            write!(f, ", '")?;
956            fmt_utf8_bytes_simple(f, param)?;
957            write!(f, "'")?;
958        }
959        write!(f, ", {:?}", self.intermediates)?;
960        write!(f, ", {:?})", self.final_byte as char)?;
961        Ok(())
962    }
963}
964
965#[cfg_attr(feature = "serde", derive(serde::Serialize))]
966#[derive(Clone, PartialEq, Eq)]
967pub struct DCSOwned {
968    pub private: Option<u8>,
969    pub params: ParamBufOwned,
970    pub intermediates: VTIntermediate,
971    pub final_byte: u8,
972}
973
974impl std::fmt::Debug for DCSOwned {
975    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
976        write!(f, "DcsStart(")?;
977        if let Some(p) = self.private {
978            write!(f, "{:?}", p as char)?;
979        }
980        for param in &self.params {
981            write!(f, ", '")?;
982            fmt_utf8_bytes_simple(f, param)?;
983            write!(f, "'")?;
984        }
985        write!(f, ", {:?}", self.intermediates)?;
986        write!(f, ", {})", self.final_byte as char)?;
987        Ok(())
988    }
989}
990
991#[cfg(test)]
992mod test {
993    use super::*;
994
995    #[test]
996    fn test_numeric_param_buf() {
997        let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
998        let numeric_param_buf = param_buf.numeric();
999        assert_eq!(
1000            numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
1001            vec![Some(1), Some(2), Some(3), Some(4), None, None]
1002        );
1003
1004        assert_eq!(numeric_param_buf.first().unwrap().sole(), None);
1005        assert_eq!(numeric_param_buf.first().unwrap().first(), Some(1));
1006        assert_eq!(numeric_param_buf.get(1).unwrap().sole(), Some(4));
1007        assert_eq!(numeric_param_buf.get(1).unwrap().first(), Some(4));
1008        assert_eq!(numeric_param_buf.get(2).unwrap().sole(), None);
1009        assert_eq!(numeric_param_buf.get(2).unwrap().first(), None);
1010
1011        assert_eq!(
1012            numeric_param_buf
1013                .try_write(&mut [0, 0, 0, 0, 0, 0])
1014                .unwrap(),
1015            &[0, 4, 0]
1016        );
1017        assert_eq!(
1018            numeric_param_buf
1019                .get(0)
1020                .unwrap()
1021                .try_write(&mut [0, 0, 0, 0, 0, 0])
1022                .unwrap(),
1023            &[1, 2, 3]
1024        );
1025    }
1026}