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.params.len())
88            }
89            VTEvent::Ss3 {
90                intermediates,
91                final_byte,
92            } => {
93                self.prefix == SS3
94                    && self.final_byte == *final_byte
95                    && self.intermediates.const_eq(intermediates)
96            }
97            VTEvent::DcsStart {
98                priv_prefix,
99                params,
100                intermediates,
101                final_byte,
102            } => {
103                self.prefix == DCS
104                    && self.final_byte == *final_byte
105                    && self.intermediates.const_eq(intermediates)
106                    && self.private == *priv_prefix
107                    && self.const_contains(params.len())
108            }
109            _ => false,
110        }
111    }
112
113    const fn const_private_eq(&self, other: &Option<u8>) -> bool {
114        match (self.private, other) {
115            (Some(a), Some(b)) => a == *b,
116            (None, None) => true,
117            _ => false,
118        }
119    }
120
121    fn const_contains(&self, len: usize) -> bool {
122        // TODO: const
123        self.param_count.contains(&(len as u8))
124    }
125}