1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
extern crate alloc;
use alloc::boxed::Box;
use alloc::vec;
use alloc::vec::Vec;
use crate::serializer::{ConfigSerializerError, Serialize, TryDeserialize};
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Peripheral {
Bcm(BcmPeripheral),
}
impl Serialize for Peripheral {
fn serialize(&self) -> Vec<u8> {
match self {
Peripheral::Bcm(peripheral) => {
let mut data = vec![0x00];
data.append(&mut peripheral.serialize());
data
}
}
}
}
impl TryDeserialize for Peripheral {
fn try_deserialize(data: &[u8]) -> Result<Box<Self>, ConfigSerializerError> {
if data.len() < 2 {
return Err(ConfigSerializerError::WrongSize);
}
match data[0] {
0x00 => Ok(Box::new(Peripheral::Bcm(*BcmPeripheral::try_deserialize(
&data[1..],
)?))),
_ => Err(ConfigSerializerError::UnknownEnumVariant),
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum BcmPeripheral {
Single(u8),
Rgb(u8, u8, u8),
Rgbw(u8, u8, u8, u8),
}
impl Serialize for BcmPeripheral {
fn serialize(&self) -> Vec<u8> {
match *self {
BcmPeripheral::Single(channel) => vec![0x00, channel],
BcmPeripheral::Rgb(r, g, b) => vec![0x01, r, g, b],
BcmPeripheral::Rgbw(r, g, b, w) => vec![0x02, r, g, b, w],
}
}
}
impl TryDeserialize for BcmPeripheral {
fn try_deserialize(data: &[u8]) -> Result<Box<Self>, ConfigSerializerError> {
if data.len() < 2 {
return Err(ConfigSerializerError::WrongSize);
}
match data[0] {
0x00 => Ok(Box::new(BcmPeripheral::Single(data[1]))),
0x01 => {
if data.len() < 4 {
return Err(ConfigSerializerError::WrongSize);
}
Ok(Box::new(BcmPeripheral::Rgb(data[1], data[2], data[3])))
}
0x02 => {
if data.len() < 5 {
return Err(ConfigSerializerError::WrongSize);
}
Ok(Box::new(BcmPeripheral::Rgbw(
data[1], data[2], data[3], data[4],
)))
}
_ => Err(ConfigSerializerError::UnknownEnumVariant),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn bcm_serialize_test() {
let value = Peripheral::Bcm(BcmPeripheral::Rgb(0xab, 0x00, 0x01));
let expected_data = vec![0x00, 0x01, 0xab, 0x00, 0x01];
assert_eq!(value.serialize(), expected_data);
}
#[test]
fn bcm_deserialize_test() {
let data = vec![0x00, 0x01, 0xab, 0x00, 0x01];
let expected_value = Box::new(Peripheral::Bcm(BcmPeripheral::Rgb(0xab, 0x00, 0x01)));
assert_eq!(Peripheral::try_deserialize(&data), Ok(expected_value));
}
}