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