1#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
10pub enum Command {
11 Message,
13 Cbor,
15 Init,
17 Ping,
19 Cancel,
21 Error,
23 KeepAlive,
25 Wink,
27 Lock,
29 Vendor(VendorCommand),
31 Unknown(u8),
33}
34
35impl From<Command> for u8 {
36 fn from(command: Command) -> Self {
37 match command {
38 Command::Message => 0x03,
39 Command::Cbor => 0x10,
40 Command::Init => 0x06,
41 Command::Ping => 0x01,
42 Command::Cancel => 0x11,
43 Command::Error => 0x3f,
44 Command::KeepAlive => 0x3b,
45 Command::Wink => 0x08,
46 Command::Lock => 0x04,
47 Command::Vendor(command) => command.into(),
48 Command::Unknown(command) => command,
49 }
50 }
51}
52
53impl From<u8> for Command {
54 fn from(value: u8) -> Self {
55 match value {
56 0x01 => Self::Ping,
57 0x03 => Self::Message,
58 0x04 => Self::Lock,
59 0x06 => Self::Init,
60 0x08 => Self::Wink,
61 0x10 => Self::Cbor,
62 0x11 => Self::Cancel,
63 0x3b => Self::KeepAlive,
64 0x3f => Self::Error,
65 _ => VendorCommand::new(value).map_or(Command::Unknown(value), Command::Vendor),
66 }
67 }
68}
69
70#[derive(Clone, Copy, Debug, Eq, Ord, PartialEq, PartialOrd)]
76pub struct VendorCommand(u8);
77
78impl VendorCommand {
79 const FIRST: u8 = 0x40;
80 const LAST: u8 = 0x7f;
81
82 pub const RANGE: core::ops::RangeInclusive<u8> = (Self::FIRST..=Self::LAST);
84
85 pub const H40: VendorCommand = VendorCommand(0x40);
87 pub const H41: VendorCommand = VendorCommand(0x41);
89 pub const H42: VendorCommand = VendorCommand(0x42);
91 pub const H43: VendorCommand = VendorCommand(0x43);
93 pub const H44: VendorCommand = VendorCommand(0x44);
95 pub const H45: VendorCommand = VendorCommand(0x45);
97 pub const H46: VendorCommand = VendorCommand(0x46);
99 pub const H47: VendorCommand = VendorCommand(0x47);
101 pub const H48: VendorCommand = VendorCommand(0x48);
103 pub const H49: VendorCommand = VendorCommand(0x49);
105 pub const H4A: VendorCommand = VendorCommand(0x4a);
107 pub const H4B: VendorCommand = VendorCommand(0x4b);
109 pub const H4C: VendorCommand = VendorCommand(0x4c);
111 pub const H4D: VendorCommand = VendorCommand(0x4d);
113 pub const H4E: VendorCommand = VendorCommand(0x4e);
115 pub const H4F: VendorCommand = VendorCommand(0x4f);
117 pub const H50: VendorCommand = VendorCommand(0x50);
119 pub const H51: VendorCommand = VendorCommand(0x51);
121 pub const H52: VendorCommand = VendorCommand(0x52);
123 pub const H53: VendorCommand = VendorCommand(0x53);
125 pub const H54: VendorCommand = VendorCommand(0x54);
127 pub const H55: VendorCommand = VendorCommand(0x55);
129 pub const H56: VendorCommand = VendorCommand(0x56);
131 pub const H57: VendorCommand = VendorCommand(0x57);
133 pub const H58: VendorCommand = VendorCommand(0x58);
135 pub const H59: VendorCommand = VendorCommand(0x59);
137 pub const H5A: VendorCommand = VendorCommand(0x5a);
139 pub const H5B: VendorCommand = VendorCommand(0x5b);
141 pub const H5C: VendorCommand = VendorCommand(0x5c);
143 pub const H5D: VendorCommand = VendorCommand(0x5d);
145 pub const H5E: VendorCommand = VendorCommand(0x5e);
147 pub const H5F: VendorCommand = VendorCommand(0x5f);
149 pub const H60: VendorCommand = VendorCommand(0x60);
151 pub const H61: VendorCommand = VendorCommand(0x61);
153 pub const H62: VendorCommand = VendorCommand(0x62);
155 pub const H63: VendorCommand = VendorCommand(0x63);
157 pub const H64: VendorCommand = VendorCommand(0x64);
159 pub const H65: VendorCommand = VendorCommand(0x65);
161 pub const H66: VendorCommand = VendorCommand(0x66);
163 pub const H67: VendorCommand = VendorCommand(0x67);
165 pub const H68: VendorCommand = VendorCommand(0x68);
167 pub const H69: VendorCommand = VendorCommand(0x69);
169 pub const H6A: VendorCommand = VendorCommand(0x6a);
171 pub const H6B: VendorCommand = VendorCommand(0x6b);
173 pub const H6C: VendorCommand = VendorCommand(0x6c);
175 pub const H6D: VendorCommand = VendorCommand(0x6d);
177 pub const H6E: VendorCommand = VendorCommand(0x6e);
179 pub const H6F: VendorCommand = VendorCommand(0x6f);
181 pub const H70: VendorCommand = VendorCommand(0x70);
183 pub const H71: VendorCommand = VendorCommand(0x71);
185 pub const H72: VendorCommand = VendorCommand(0x72);
187 pub const H73: VendorCommand = VendorCommand(0x73);
189 pub const H74: VendorCommand = VendorCommand(0x74);
191 pub const H75: VendorCommand = VendorCommand(0x75);
193 pub const H76: VendorCommand = VendorCommand(0x76);
195 pub const H77: VendorCommand = VendorCommand(0x77);
197 pub const H78: VendorCommand = VendorCommand(0x78);
199 pub const H79: VendorCommand = VendorCommand(0x79);
201 pub const H7A: VendorCommand = VendorCommand(0x7a);
203 pub const H7B: VendorCommand = VendorCommand(0x7b);
205 pub const H7C: VendorCommand = VendorCommand(0x7c);
207 pub const H7D: VendorCommand = VendorCommand(0x7d);
209 pub const H7E: VendorCommand = VendorCommand(0x7e);
211 pub const H7F: VendorCommand = VendorCommand(0x7f);
213
214 pub fn new(id: u8) -> Option<Self> {
216 if Self::RANGE.contains(&id) {
217 Some(Self(id))
218 } else {
219 None
220 }
221 }
222}
223
224impl From<VendorCommand> for u8 {
225 fn from(command: VendorCommand) -> u8 {
226 command.0
227 }
228}
229
230#[cfg(test)]
231mod test {
232 use super::{Command, VendorCommand};
233
234 impl quickcheck::Arbitrary for Command {
235 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
236 u8::arbitrary(g).into()
237 }
238
239 fn shrink(&self) -> Box<dyn Iterator<Item = Self>> {
240 Box::new(u8::from(*self).shrink().map(From::from))
241 }
242 }
243
244 impl quickcheck::Arbitrary for VendorCommand {
245 fn arbitrary(g: &mut quickcheck::Gen) -> Self {
246 let n = VendorCommand::RANGE.end() - VendorCommand::RANGE.start() + 1;
247 let command = u8::arbitrary(g) % n + VendorCommand::RANGE.start();
248 VendorCommand::new(command).unwrap()
249 }
250 }
251}