1#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8#[repr(u8)]
9pub enum Verb {
10 Scan = 0x01,
13 Format = 0x02,
15 Search = 0x03,
17 EndStream = 0x04,
19
20 Ping = 0x05,
23 Ok = 0x06,
25 Alert = 0x07,
27
28 Back = 0x08,
31 Context = 0x09,
33 Next = 0x0A,
35
36 Stats = 0x0B,
39 Clear = 0x0C,
41 Complete = 0x0D,
43
44 AuthStart = 0x0E,
47 AuthEnd = 0x0F,
49
50 Audio = 0x10,
53
54 Permit = 0x11,
57 Deny = 0x12,
59 Elevate = 0x13,
61 Audit = 0x14,
63
64 Error = 0x15,
67 Subscribe = 0x16,
69 Unsubscribe = 0x17,
71 Cancel = 0x18,
73
74 M8Wave = 0x19,
77 Remember = 0x1A,
79 Recall = 0x1C,
81 Forget = 0x1D,
83
84 Session = 0x1E,
87 User = 0x1F,
89}
90
91impl Verb {
92 pub fn from_byte(b: u8) -> Option<Self> {
94 match b {
95 0x01 => Some(Verb::Scan),
96 0x02 => Some(Verb::Format),
97 0x03 => Some(Verb::Search),
98 0x04 => Some(Verb::EndStream),
99 0x05 => Some(Verb::Ping),
100 0x06 => Some(Verb::Ok),
101 0x07 => Some(Verb::Alert),
102 0x08 => Some(Verb::Back),
103 0x09 => Some(Verb::Context),
104 0x0A => Some(Verb::Next),
105 0x0B => Some(Verb::Stats),
106 0x0C => Some(Verb::Clear),
107 0x0D => Some(Verb::Complete),
108 0x0E => Some(Verb::AuthStart),
109 0x0F => Some(Verb::AuthEnd),
110 0x10 => Some(Verb::Audio),
111 0x11 => Some(Verb::Permit),
112 0x12 => Some(Verb::Deny),
113 0x13 => Some(Verb::Elevate),
114 0x14 => Some(Verb::Audit),
115 0x15 => Some(Verb::Error),
116 0x16 => Some(Verb::Subscribe),
117 0x17 => Some(Verb::Unsubscribe),
118 0x18 => Some(Verb::Cancel),
119 0x19 => Some(Verb::M8Wave),
120 0x1A => Some(Verb::Remember),
121 0x1C => Some(Verb::Recall),
122 0x1D => Some(Verb::Forget),
123 0x1E => Some(Verb::Session),
124 0x1F => Some(Verb::User),
125 _ => None,
126 }
127 }
128
129 #[inline]
131 pub fn as_byte(self) -> u8 {
132 self as u8
133 }
134
135 pub fn requires_auth(self) -> bool {
137 matches!(
138 self,
139 Verb::Format
140 | Verb::Clear
141 | Verb::Permit
142 | Verb::Deny
143 | Verb::Elevate
144 | Verb::Remember
145 | Verb::Forget
146 )
147 }
148
149 pub fn security_level(self) -> u8 {
151 match self {
152 Verb::Scan | Verb::Search | Verb::Stats | Verb::Ping |
154 Verb::Context | Verb::Recall | Verb::Format |
155 Verb::Remember | Verb::Forget | Verb::M8Wave | Verb::Audio => 0,
156
157 Verb::Clear | Verb::Subscribe | Verb::Unsubscribe => 1,
159
160 Verb::Elevate => 2,
162
163 Verb::Permit | Verb::Deny | Verb::Audit => 3,
165
166 _ => 1,
168 }
169 }
170
171 pub fn name(self) -> &'static str {
173 match self {
174 Verb::Scan => "SCAN",
175 Verb::Format => "FORMAT",
176 Verb::Search => "SEARCH",
177 Verb::EndStream => "END_STREAM",
178 Verb::Ping => "PING",
179 Verb::Ok => "OK",
180 Verb::Alert => "ALERT",
181 Verb::Back => "BACK",
182 Verb::Context => "CONTEXT",
183 Verb::Next => "NEXT",
184 Verb::Stats => "STATS",
185 Verb::Clear => "CLEAR",
186 Verb::Complete => "COMPLETE",
187 Verb::AuthStart => "AUTH_START",
188 Verb::AuthEnd => "AUTH_END",
189 Verb::Audio => "AUDIO",
190 Verb::Permit => "PERMIT",
191 Verb::Deny => "DENY",
192 Verb::Elevate => "ELEVATE",
193 Verb::Audit => "AUDIT",
194 Verb::Error => "ERROR",
195 Verb::Subscribe => "SUBSCRIBE",
196 Verb::Unsubscribe => "UNSUBSCRIBE",
197 Verb::Cancel => "CANCEL",
198 Verb::M8Wave => "M8_WAVE",
199 Verb::Remember => "REMEMBER",
200 Verb::Recall => "RECALL",
201 Verb::Forget => "FORGET",
202 Verb::Session => "SESSION",
203 Verb::User => "USER",
204 }
205 }
206}
207
208#[cfg(test)]
209mod tests {
210 use super::*;
211
212 #[test]
213 fn test_verb_roundtrip() {
214 for b in 0x01..=0x1F {
215 if let Some(verb) = Verb::from_byte(b) {
216 assert_eq!(verb.as_byte(), b);
217 }
218 }
219 }
220
221 #[test]
222 fn test_ping_is_0x05() {
223 assert_eq!(Verb::Ping.as_byte(), 0x05);
224 }
225
226 #[test]
227 fn test_security_levels() {
228 assert_eq!(Verb::Scan.security_level(), 0);
230 assert_eq!(Verb::Search.security_level(), 0);
231 assert_eq!(Verb::Ping.security_level(), 0);
232
233 assert_eq!(Verb::Permit.security_level(), 3);
235 assert_eq!(Verb::Deny.security_level(), 3);
236 }
237}