vt_push_parser/
event.rs

1//! Event types.
2use std::{io, 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<'a>> {
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    /// Encode the event into the provided writer, returning the number of bytes
634    /// written.
635    ///
636    /// If the write fails for any reason, it is not possible to determine how
637    /// many bytes were written.
638    ///
639    /// The order of writes is not specified and may change between versions of
640    /// this crate.
641    pub fn write_to(&self, mut writer: impl io::Write) -> Result<usize, io::Error> {
642        use crate::{BEL, CAN, CSI, DCS, ESC, OSC, SS2, SS3, ST_FINAL};
643
644        use VTEvent::*;
645        let mut len = 0;
646        match self {
647            Raw(s) | OscData(s) | DcsData(s) => {
648                writer.write_all(s)?;
649                len = s.len();
650            }
651            EscInvalid(esc_invalid) => {
652                use self::EscInvalid::*;
653                match esc_invalid {
654                    One(b) => {
655                        writer.write_all(&[ESC, *b])?;
656                        len = 2;
657                    }
658                    Two(b1, b2) => {
659                        writer.write_all(&[ESC, *b1, *b2])?;
660                        len = 3;
661                    }
662                    Three(b1, b2, b3) => {
663                        writer.write_all(&[ESC, *b1, *b2, *b3])?;
664                        len = 4;
665                    }
666                    Four(b1, b2, b3, b4) => {
667                        writer.write_all(&[ESC, *b1, *b2, *b3, *b4])?;
668                        len = 5;
669                    }
670                }
671            }
672            OscCancel | DcsCancel => {
673                writer.write_all(&[CAN])?;
674                len = 1;
675            }
676            C0(b) => {
677                writer.write_all(&[*b])?;
678                len = 1;
679            }
680            Ss2(ss2) => {
681                writer.write_all(&[ESC, SS2, ss2.char])?;
682                len = 3;
683            }
684            Ss3(ss3) => {
685                writer.write_all(&[ESC, SS3, ss3.char])?;
686                len = 3;
687            }
688            Esc(esc) => {
689                writer.write_all(&[ESC])?;
690                len = 1;
691                if let Some(p) = esc.private {
692                    writer.write_all(&[p])?;
693                    len = 2;
694                }
695                if !esc.intermediates.is_empty() {
696                    writer.write_all(&esc.intermediates.data[..esc.intermediates.len()])?;
697                    len += esc.intermediates.len();
698                }
699                writer.write_all(&[esc.final_byte])?;
700                len += 1;
701            }
702            Csi(csi) => {
703                writer.write_all(&[ESC, CSI])?;
704                len = 2;
705                if let Some(p) = csi.private {
706                    writer.write_all(&[p])?;
707                    len = 3;
708                }
709                let mut first = true;
710                for param in csi.params {
711                    if !first {
712                        writer.write_all(b";")?;
713                        len += 1;
714                    } else {
715                        first = false;
716                    }
717                    writer.write_all(param)?;
718                    len += param.len();
719                }
720                if !csi.intermediates.is_empty() {
721                    writer.write_all(&csi.intermediates.data[..csi.intermediates.len()])?;
722                    len += csi.intermediates.len();
723                }
724                writer.write_all(&[csi.final_byte])?;
725                len += 1;
726            }
727            DcsStart(dcs_start) => {
728                writer.write_all(&[ESC, DCS])?;
729                len = 2;
730                if let Some(p) = dcs_start.private {
731                    writer.write_all(&[p])?;
732                    len = 3;
733                }
734                let mut first = true;
735                for param in dcs_start.params {
736                    if !first {
737                        writer.write_all(b";")?;
738                        len += 1;
739                    } else {
740                        first = false;
741                    }
742                    writer.write_all(param)?;
743                    len += param.len();
744                }
745                if !dcs_start.intermediates.is_empty() {
746                    writer.write_all(
747                        &dcs_start.intermediates.data[..dcs_start.intermediates.len()],
748                    )?;
749                    len += dcs_start.intermediates.len();
750                }
751                writer.write_all(&[dcs_start.final_byte])?;
752                len += 1;
753            }
754            DcsEnd(s) => {
755                writer.write_all(s)?;
756                len += s.len();
757                writer.write_all(&[ESC, ST_FINAL])?;
758                len += 2;
759            }
760            OscStart => {
761                writer.write_all(&[ESC, OSC])?;
762                len = 2;
763            }
764            OscEnd { data, used_bel } => {
765                writer.write_all(data)?;
766                if *used_bel {
767                    writer.write_all(&[BEL])?;
768                    len = 1 + data.len();
769                } else {
770                    writer.write_all(&[ESC, ST_FINAL])?;
771                    len = 2 + data.len();
772                }
773            }
774        }
775        Ok(len)
776    }
777
778    pub fn to_owned(&self) -> VTOwnedEvent {
779        use VTEvent::*;
780        match self {
781            Raw(s) => VTOwnedEvent::Raw(s.to_vec()),
782            C0(b) => VTOwnedEvent::C0(*b),
783            Esc(esc) => VTOwnedEvent::Esc(*esc),
784            EscInvalid(esc_invalid) => VTOwnedEvent::EscInvalid(*esc_invalid),
785            Ss2(ss2) => VTOwnedEvent::Ss2(*ss2),
786            Ss3(ss3) => VTOwnedEvent::Ss3(*ss3),
787            Csi(csi) => VTOwnedEvent::Csi(CSIOwned {
788                private: csi.private,
789                params: csi.params.to_owned(),
790                intermediates: csi.intermediates,
791                final_byte: csi.final_byte,
792            }),
793            DcsStart(dcs_start) => VTOwnedEvent::DcsStart(DCSOwned {
794                private: dcs_start.private,
795                params: dcs_start.params.to_owned(),
796                intermediates: dcs_start.intermediates,
797                final_byte: dcs_start.final_byte,
798            }),
799            DcsData(s) => VTOwnedEvent::DcsData(s.to_vec()),
800            DcsEnd(s) => VTOwnedEvent::DcsEnd(s.to_vec()),
801            DcsCancel => VTOwnedEvent::DcsCancel,
802            OscStart => VTOwnedEvent::OscStart,
803            OscData(s) => VTOwnedEvent::OscData(s.to_vec()),
804            OscEnd { data, used_bel } => VTOwnedEvent::OscEnd {
805                data: data.to_vec(),
806                used_bel: *used_bel,
807            },
808            OscCancel => VTOwnedEvent::OscCancel,
809        }
810    }
811}
812
813#[cfg_attr(feature = "serde", derive(serde::Serialize))]
814#[derive(Clone, PartialEq, Eq, Debug, Default)]
815pub struct ParamBufOwned {
816    pub(crate) params: Params,
817}
818
819impl IntoIterator for ParamBufOwned {
820    type Item = Param;
821    type IntoIter = <Params as IntoIterator>::IntoIter;
822    fn into_iter(self) -> Self::IntoIter {
823        self.params.into_iter()
824    }
825}
826
827impl<'b> IntoIterator for &'b ParamBufOwned {
828    type Item = &'b [u8];
829    type IntoIter = Map<std::slice::Iter<'b, Param>, fn(&Param) -> &[u8]>;
830    fn into_iter(self) -> Self::IntoIter {
831        self.params.iter().map(|p| p.as_slice())
832    }
833}
834
835impl ParamBufOwned {
836    /// Create an empty `ParamBufOwned`.
837    pub const fn empty() -> Self {
838        Self {
839            params: SmallVec::new_const(),
840        }
841    }
842
843    /// Create a `ParamBufOwned` from a slice of slices.
844    pub fn new(params: &[&[u8]]) -> Self {
845        Self {
846            params: params.iter().map(|p| Param::from(*p)).collect(),
847        }
848    }
849
850    pub fn len(&self) -> usize {
851        self.params.len()
852    }
853
854    pub fn is_empty(&self) -> bool {
855        self.params.is_empty()
856    }
857
858    pub fn get(&self, index: usize) -> Option<&[u8]> {
859        self.params.get(index).map(|p| p.as_slice())
860    }
861
862    pub fn try_parse<T: std::str::FromStr>(&self, index: usize) -> Option<T> {
863        self.params.get(index).and_then(|p| {
864            std::str::from_utf8(p.as_slice())
865                .ok()
866                .and_then(|s| s.parse::<T>().ok())
867        })
868    }
869
870    pub fn borrow(&self) -> ParamBuf<'_> {
871        ParamBuf {
872            params: &self.params,
873        }
874    }
875
876    pub fn numeric(&self) -> NumericParamBuf<'_> {
877        NumericParamBuf {
878            params: &self.params,
879        }
880    }
881}
882
883/// A union of all possible events that can be emitted by the parser, with owned
884/// data.
885#[cfg_attr(feature = "serde", derive(serde::Serialize))]
886#[derive(Clone, PartialEq, Eq)]
887pub enum VTOwnedEvent {
888    Raw(Vec<u8>),
889    C0(u8),
890    Esc(Esc),
891    EscInvalid(EscInvalid),
892    Ss2(SS2),
893    Ss3(SS3),
894    Csi(CSIOwned),
895    DcsStart(DCSOwned),
896    DcsData(Vec<u8>),
897    DcsEnd(Vec<u8>),
898    DcsCancel,
899    OscStart,
900    OscData(Vec<u8>),
901    OscEnd { data: Vec<u8>, used_bel: bool },
902    OscCancel,
903}
904
905impl std::fmt::Debug for VTOwnedEvent {
906    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
907        self.borrow().fmt(f)
908    }
909}
910
911impl VTOwnedEvent {
912    pub fn borrow(&self) -> VTEvent<'_> {
913        match self {
914            VTOwnedEvent::Raw(s) => VTEvent::Raw(s),
915            VTOwnedEvent::C0(b) => VTEvent::C0(*b),
916            VTOwnedEvent::Esc(esc) => VTEvent::Esc(*esc),
917            VTOwnedEvent::EscInvalid(esc_invalid) => VTEvent::EscInvalid(*esc_invalid),
918            VTOwnedEvent::Ss2(ss2) => VTEvent::Ss2(SS2 { char: ss2.char }),
919            VTOwnedEvent::Ss3(ss3) => VTEvent::Ss3(SS3 { char: ss3.char }),
920            VTOwnedEvent::Csi(csi) => VTEvent::Csi(CSI {
921                private: csi.private,
922                params: csi.params.borrow(),
923                intermediates: csi.intermediates,
924                final_byte: csi.final_byte,
925            }),
926            VTOwnedEvent::DcsStart(dcs_start) => VTEvent::DcsStart(DCS {
927                private: dcs_start.private,
928                params: dcs_start.params.borrow(),
929                intermediates: dcs_start.intermediates,
930                final_byte: dcs_start.final_byte,
931            }),
932            VTOwnedEvent::DcsData(s) => VTEvent::DcsData(s),
933            VTOwnedEvent::DcsEnd(s) => VTEvent::DcsEnd(s),
934            VTOwnedEvent::DcsCancel => VTEvent::DcsCancel,
935            VTOwnedEvent::OscStart => VTEvent::OscStart,
936            VTOwnedEvent::OscData(s) => VTEvent::OscData(s),
937            VTOwnedEvent::OscEnd { data, used_bel } => VTEvent::OscEnd {
938                data,
939                used_bel: *used_bel,
940            },
941            VTOwnedEvent::OscCancel => VTEvent::OscCancel,
942        }
943    }
944}
945
946/// An invalid escape sequence.
947#[cfg_attr(feature = "serde", derive(serde::Serialize))]
948#[derive(Clone, Copy, PartialEq, Eq, Hash)]
949pub enum EscInvalid {
950    One(u8),
951    Two(u8, u8),
952    Three(u8, u8, u8),
953    Four(u8, u8, u8, u8),
954}
955
956impl std::fmt::Debug for EscInvalid {
957    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
958        match self {
959            EscInvalid::One(b) => write!(f, "EscInvalid(1B {b:02X})")?,
960            EscInvalid::Two(b1, b2) => write!(f, "EscInvalid(1B {b1:02X} {b2:02X})")?,
961            EscInvalid::Three(b1, b2, b3) => {
962                write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X})")?
963            }
964            EscInvalid::Four(b1, b2, b3, b4) => {
965                write!(f, "EscInvalid(1B {b1:02X} {b2:02X} {b3:02X} {b4:02X})")?
966            }
967        }
968        Ok(())
969    }
970}
971
972#[cfg_attr(feature = "serde", derive(serde::Serialize))]
973#[derive(Clone, Copy, PartialEq, Eq, Hash)]
974pub struct Esc {
975    pub intermediates: VTIntermediate,
976    pub private: Option<u8>,
977    pub final_byte: u8,
978}
979
980impl std::fmt::Debug for Esc {
981    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
982        write!(f, "Esc(")?;
983        if let Some(p) = self.private {
984            write!(f, "{:?}, ", p as char)?;
985        }
986        write!(f, "{:?}, ", self.intermediates)?;
987        if let Ok(c) = AsciiControl::try_from(self.final_byte as char) {
988            write!(f, "{c})")?;
989        } else {
990            write!(f, "{})", self.final_byte as char)?;
991        }
992        Ok(())
993    }
994}
995
996#[cfg_attr(feature = "serde", derive(serde::Serialize))]
997#[derive(Clone, Copy, PartialEq, Eq, Hash)]
998pub struct SS2 {
999    pub char: u8,
1000}
1001
1002impl std::fmt::Debug for SS2 {
1003    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1004        write!(f, "Ss2(")?;
1005        if let Ok(c) = AsciiControl::try_from(self.char as char) {
1006            write!(f, "{c})")?;
1007        } else {
1008            write!(f, "{:?})", self.char as char)?;
1009        }
1010        Ok(())
1011    }
1012}
1013
1014#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1015#[derive(Clone, Copy, PartialEq, Eq, Hash)]
1016pub struct SS3 {
1017    pub char: u8,
1018}
1019
1020impl std::fmt::Debug for SS3 {
1021    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1022        write!(f, "Ss3(")?;
1023        if let Ok(c) = AsciiControl::try_from(self.char as char) {
1024            write!(f, "{c})")?;
1025        } else {
1026            write!(f, "{:?})", self.char as char)?;
1027        }
1028        Ok(())
1029    }
1030}
1031
1032#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1033#[derive(Clone, PartialEq, Eq, Hash)]
1034pub struct CSI<'a> {
1035    pub private: Option<u8>,
1036    pub params: ParamBuf<'a>,
1037    pub intermediates: VTIntermediate,
1038    pub final_byte: u8,
1039}
1040
1041impl<'a> std::fmt::Debug for CSI<'a> {
1042    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1043        write!(f, "Csi(")?;
1044        if let Some(p) = self.private {
1045            write!(f, "{:?}, ", p as char)?;
1046        }
1047        for param in &self.params {
1048            write!(f, "'")?;
1049            fmt_utf8_bytes_simple(f, param)?;
1050            write!(f, "', ")?;
1051        }
1052        write!(f, "{:?}, ", self.intermediates)?;
1053        write!(f, "{:?})", self.final_byte as char)?;
1054        Ok(())
1055    }
1056}
1057
1058#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1059#[derive(Clone, PartialEq, Eq, Hash)]
1060pub struct DCS<'a> {
1061    pub private: Option<u8>,
1062    pub params: ParamBuf<'a>,
1063    pub intermediates: VTIntermediate,
1064    pub final_byte: u8,
1065}
1066
1067impl<'a> std::fmt::Debug for DCS<'a> {
1068    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1069        write!(f, "DcsStart(")?;
1070        if let Some(p) = self.private {
1071            write!(f, "{:?}, ", p as char)?;
1072        }
1073        for param in &self.params {
1074            write!(f, "'")?;
1075            fmt_utf8_bytes_simple(f, param)?;
1076            write!(f, "', ")?;
1077        }
1078        write!(f, "{:?}, ", self.intermediates)?;
1079        write!(f, "{})", self.final_byte as char)?;
1080        Ok(())
1081    }
1082}
1083
1084#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1085#[derive(Clone, PartialEq, Eq)]
1086pub struct CSIOwned {
1087    pub private: Option<u8>,
1088    pub params: ParamBufOwned,
1089    pub intermediates: VTIntermediate,
1090    pub final_byte: u8,
1091}
1092
1093impl std::fmt::Debug for CSIOwned {
1094    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1095        write!(f, "Csi(")?;
1096        if let Some(p) = self.private {
1097            write!(f, "{:?}", p as char)?;
1098        }
1099        for param in &self.params {
1100            write!(f, ", '")?;
1101            fmt_utf8_bytes_simple(f, param)?;
1102            write!(f, "'")?;
1103        }
1104        write!(f, ", {:?}", self.intermediates)?;
1105        write!(f, ", {:?})", self.final_byte as char)?;
1106        Ok(())
1107    }
1108}
1109
1110#[cfg_attr(feature = "serde", derive(serde::Serialize))]
1111#[derive(Clone, PartialEq, Eq)]
1112pub struct DCSOwned {
1113    pub private: Option<u8>,
1114    pub params: ParamBufOwned,
1115    pub intermediates: VTIntermediate,
1116    pub final_byte: u8,
1117}
1118
1119impl std::fmt::Debug for DCSOwned {
1120    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
1121        write!(f, "DcsStart(")?;
1122        if let Some(p) = self.private {
1123            write!(f, "{:?}", p as char)?;
1124        }
1125        for param in &self.params {
1126            write!(f, ", '")?;
1127            fmt_utf8_bytes_simple(f, param)?;
1128            write!(f, "'")?;
1129        }
1130        write!(f, ", {:?}", self.intermediates)?;
1131        write!(f, ", {})", self.final_byte as char)?;
1132        Ok(())
1133    }
1134}
1135
1136#[cfg(test)]
1137mod test {
1138    use super::*;
1139
1140    #[test]
1141    fn test_numeric_param_buf() {
1142        let param_buf = ParamBufOwned::new(&[b"1:2:3", b"4", b":"]);
1143        let numeric_param_buf = param_buf.numeric();
1144        assert_eq!(
1145            numeric_param_buf.into_iter().flatten().collect::<Vec<_>>(),
1146            vec![Some(1), Some(2), Some(3), Some(4), None, None]
1147        );
1148
1149        assert_eq!(numeric_param_buf.first().unwrap().sole(), None);
1150        assert_eq!(numeric_param_buf.first().unwrap().first(), Some(1));
1151        assert_eq!(numeric_param_buf.get(1).unwrap().sole(), Some(4));
1152        assert_eq!(numeric_param_buf.get(1).unwrap().first(), Some(4));
1153        assert_eq!(numeric_param_buf.get(2).unwrap().sole(), None);
1154        assert_eq!(numeric_param_buf.get(2).unwrap().first(), None);
1155
1156        assert_eq!(
1157            numeric_param_buf
1158                .try_write(&mut [0, 0, 0, 0, 0, 0])
1159                .unwrap(),
1160            &[0, 4, 0]
1161        );
1162        assert_eq!(
1163            numeric_param_buf
1164                .get(0)
1165                .unwrap()
1166                .try_write(&mut [0, 0, 0, 0, 0, 0])
1167                .unwrap(),
1168            &[1, 2, 3]
1169        );
1170    }
1171}