Coverage Report

Created: 2025-06-23 13:53

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/build/cargo-vendor-dir/anstyle-parse-0.2.6/src/state/definitions.rs
Line
Count
Source
1
#![allow(clippy::exhaustive_enums)]
2
3
use core::mem;
4
5
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
6
#[repr(u8)]
7
#[derive(Default)]
8
pub enum State {
9
    Anywhere = 0,
10
    CsiEntry = 1,
11
    CsiIgnore = 2,
12
    CsiIntermediate = 3,
13
    CsiParam = 4,
14
    DcsEntry = 5,
15
    DcsIgnore = 6,
16
    DcsIntermediate = 7,
17
    DcsParam = 8,
18
    DcsPassthrough = 9,
19
    Escape = 10,
20
    EscapeIntermediate = 11,
21
    #[default]
22
    Ground = 12,
23
    OscString = 13,
24
    SosPmApcString = 14,
25
    Utf8 = 15,
26
}
27
28
impl TryFrom<u8> for State {
29
    type Error = u8;
30
31
    #[inline(always)]
32
0
    fn try_from(raw: u8) -> Result<Self, Self::Error> {
33
0
        STATES.get(raw as usize).ok_or(raw).copied()
34
0
    }
35
}
36
37
const STATES: [State; 16] = [
38
    State::Anywhere,
39
    State::CsiEntry,
40
    State::CsiIgnore,
41
    State::CsiIntermediate,
42
    State::CsiParam,
43
    State::DcsEntry,
44
    State::DcsIgnore,
45
    State::DcsIntermediate,
46
    State::DcsParam,
47
    State::DcsPassthrough,
48
    State::Escape,
49
    State::EscapeIntermediate,
50
    State::Ground,
51
    State::OscString,
52
    State::SosPmApcString,
53
    State::Utf8,
54
];
55
56
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
57
#[repr(u8)]
58
#[derive(Default)]
59
pub enum Action {
60
    #[default]
61
    Nop = 0,
62
    Clear = 1,
63
    Collect = 2,
64
    CsiDispatch = 3,
65
    EscDispatch = 4,
66
    Execute = 5,
67
    Hook = 6,
68
    Ignore = 7,
69
    OscEnd = 8,
70
    OscPut = 9,
71
    OscStart = 10,
72
    Param = 11,
73
    Print = 12,
74
    Put = 13,
75
    Unhook = 14,
76
    BeginUtf8 = 15,
77
}
78
79
impl TryFrom<u8> for Action {
80
    type Error = u8;
81
82
    #[inline(always)]
83
0
    fn try_from(raw: u8) -> Result<Self, Self::Error> {
84
0
        ACTIONS.get(raw as usize).ok_or(raw).copied()
85
0
    }
86
}
87
88
const ACTIONS: [Action; 16] = [
89
    Action::Nop,
90
    Action::Clear,
91
    Action::Collect,
92
    Action::CsiDispatch,
93
    Action::EscDispatch,
94
    Action::Execute,
95
    Action::Hook,
96
    Action::Ignore,
97
    Action::OscEnd,
98
    Action::OscPut,
99
    Action::OscStart,
100
    Action::Param,
101
    Action::Print,
102
    Action::Put,
103
    Action::Unhook,
104
    Action::BeginUtf8,
105
];
106
107
/// Unpack a u8 into a State and Action
108
///
109
/// The implementation of this assumes that there are *precisely* 16 variants for both Action and
110
/// State. Furthermore, it assumes that the enums are tag-only; that is, there is no data in any
111
/// variant.
112
///
113
/// Bad things will happen if those invariants are violated.
114
#[inline(always)]
115
0
pub(crate) const fn unpack(delta: u8) -> (State, Action) {
116
0
    unsafe {
117
0
        (
118
0
            // State is stored in bottom 4 bits
119
0
            mem::transmute::<u8, State>(delta & 0x0f),
120
0
            // Action is stored in top 4 bits
121
0
            mem::transmute::<u8, Action>(delta >> 4),
122
0
        )
123
0
    }
124
0
}
125
126
#[inline(always)]
127
#[cfg(test)]
128
pub(crate) const fn pack(state: State, action: Action) -> u8 {
129
    (action as u8) << 4 | state as u8
130
}
131
132
#[cfg(test)]
133
mod tests {
134
    use super::*;
135
136
    #[test]
137
    fn unpack_state_action() {
138
        match unpack(0xee) {
139
            (State::SosPmApcString, Action::Unhook) => (),
140
            _ => panic!("unpack failed"),
141
        }
142
143
        match unpack(0x0f) {
144
            (State::Utf8, Action::Nop) => (),
145
            _ => panic!("unpack failed"),
146
        }
147
148
        match unpack(0xff) {
149
            (State::Utf8, Action::BeginUtf8) => (),
150
            _ => panic!("unpack failed"),
151
        }
152
    }
153
154
    #[test]
155
    fn pack_state_action() {
156
        match unpack(0xee) {
157
            (State::SosPmApcString, Action::Unhook) => (),
158
            _ => panic!("unpack failed"),
159
        }
160
161
        match unpack(0x0f) {
162
            (State::Utf8, Action::Nop) => (),
163
            _ => panic!("unpack failed"),
164
        }
165
166
        match unpack(0xff) {
167
            (State::Utf8, Action::BeginUtf8) => (),
168
            _ => panic!("unpack failed"),
169
        }
170
    }
171
}