vt_push_parser/
signature.rs

1use std::ops::Range;
2
3use crate::event::{VTEvent, VTIntermediate};
4
5const CSI: u8 = b'[';
6const SS3: u8 = b'O';
7const DCS: u8 = b'P';
8const OSC: u8 = b']';
9
10/// A signature for an escape sequence.
11pub struct VTEscapeSignature {
12    pub prefix: u8,
13    pub private: Option<u8>,
14    pub intermediates: VTIntermediate,
15    pub final_byte: u8,
16    pub param_count: Range<u8>,
17}
18
19impl VTEscapeSignature {
20    pub const fn csi(
21        private: Option<u8>,
22        param_count: Range<u8>,
23        intermediates: VTIntermediate,
24        final_byte: u8,
25    ) -> Self {
26        Self {
27            prefix: CSI,
28            private,
29            intermediates,
30            final_byte,
31            param_count,
32        }
33    }
34
35    pub const fn ss3(intermediates: VTIntermediate, final_byte: u8) -> Self {
36        Self {
37            prefix: SS3,
38            private: None,
39            intermediates,
40            final_byte,
41            param_count: u8::MIN..u8::MAX,
42        }
43    }
44
45    pub const fn dcs(
46        priv_prefix: Option<u8>,
47        param_count: Range<u8>,
48        intermediates: VTIntermediate,
49        final_byte: u8,
50    ) -> Self {
51        Self {
52            prefix: DCS,
53            private: priv_prefix,
54            intermediates,
55            final_byte,
56            param_count,
57        }
58    }
59
60    pub const fn osc(intermediates: VTIntermediate, final_byte: u8) -> Self {
61        Self {
62            prefix: OSC,
63            private: None,
64            intermediates,
65            final_byte,
66            param_count: u8::MIN..u8::MAX,
67        }
68    }
69
70    pub fn matches(&self, entry: &VTEvent) -> bool {
71        // TODO: const
72        match entry {
73            VTEvent::Esc {
74                intermediates,
75                final_byte,
76            } => self.final_byte == *final_byte && self.intermediates.const_eq(intermediates),
77            VTEvent::Csi {
78                private,
79                params,
80                intermediates,
81                final_byte,
82            } => {
83                self.prefix == CSI
84                    && self.final_byte == *final_byte
85                    && self.intermediates.const_eq(intermediates)
86                    && self.const_private_eq(private)
87                    && self.const_contains(params.len())
88            }
89            VTEvent::DcsStart {
90                private,
91                params,
92                intermediates,
93                final_byte,
94            } => {
95                self.prefix == DCS
96                    && self.final_byte == *final_byte
97                    && self.intermediates.const_eq(intermediates)
98                    && self.private == *private
99                    && self.const_contains(params.len())
100            }
101            _ => false,
102        }
103    }
104
105    const fn const_private_eq(&self, other: &Option<u8>) -> bool {
106        match (self.private, other) {
107            (Some(a), Some(b)) => a == *b,
108            (None, None) => true,
109            _ => false,
110        }
111    }
112
113    fn const_contains(&self, len: usize) -> bool {
114        // TODO: const
115        self.param_count.contains(&(len as u8))
116    }
117}