1use serde::{ser::SerializeStruct, Serialize};
2
3#[derive(Debug, Clone, Serialize)]
4#[serde(rename_all = "UPPERCASE")]
5pub struct ItemSetValue {
6 #[serde(flatten)]
7 pub value: SetValue,
8
9 pub number: u32,
10}
11
12#[derive(Debug, Clone, Copy)]
14pub enum SetValue {
15 On(ClickDuration),
16
17 Off(ClickDuration),
18
19 Dimm(u8),
20
21 Blinds(u8),
22}
23
24impl Serialize for SetValue {
25 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
26 where
27 S: serde::Serializer,
28 {
29 fn serialize_state<S>(state: &str, serializer: S) -> Result<S::Ok, S::Error>
30 where
31 S: serde::Serializer,
32 {
33 let mut s = serializer.serialize_struct("SetValue", 1)?;
34 s.serialize_field("STATE", state)?;
35 s.end()
36 }
37
38 fn serialize_state_long<S>(state: &str, serializer: S) -> Result<S::Ok, S::Error>
39 where
40 S: serde::Serializer,
41 {
42 let mut s = serializer.serialize_struct("SetValue", 2)?;
43 s.serialize_field("STATE", state)?;
44 s.serialize_field("LONG_CLICK", "ON")?;
45 s.end()
46 }
47
48 fn serialize_value<S>(state: &str, value: &u8, serializer: S) -> Result<S::Ok, S::Error>
49 where
50 S: serde::Serializer,
51 {
52 let mut s = serializer.serialize_struct("SetValue", 2)?;
53 s.serialize_field("STATE", state)?;
54 s.serialize_field("VALUE", value)?;
55 s.end()
56 }
57
58 match self {
59 SetValue::On(ClickDuration::Short) => serialize_state("ON", serializer),
60 SetValue::On(ClickDuration::Long) => serialize_state_long("ON", serializer),
61 SetValue::Off(ClickDuration::Short) => serialize_state("OFF", serializer),
62 SetValue::Off(ClickDuration::Long) => serialize_state_long("OFF", serializer),
63 SetValue::Dimm(v) => serialize_value("VALUE_DIMM", v, serializer),
64 SetValue::Blinds(v) => serialize_value("VALUE_BLINDS", v, serializer),
65 }
66 }
67}
68
69#[derive(Debug, Clone, Copy)]
70pub enum ClickDuration {
71 Short,
72 Long,
73}
74
75#[cfg(test)]
76mod tests {
77 use serde_test::{assert_ser_tokens, Token};
78
79 use super::*;
80
81 fn item(value: SetValue) -> ItemSetValue {
82 ItemSetValue { value, number: 1 }
83 }
84
85 #[test]
86 fn item_set_value_on_short() {
87 assert_ser_tokens(
88 &item(SetValue::On(ClickDuration::Short)),
89 &[
90 Token::Map { len: None },
91 Token::Str("STATE"),
92 Token::Str("ON"),
93 Token::Str("NUMBER"),
94 Token::U32(1),
95 Token::MapEnd,
96 ],
97 )
98 }
99
100 #[test]
101 fn item_set_value_off_short() {
102 assert_ser_tokens(
103 &item(SetValue::Off(ClickDuration::Short)),
104 &[
105 Token::Map { len: None },
106 Token::Str("STATE"),
107 Token::Str("OFF"),
108 Token::Str("NUMBER"),
109 Token::U32(1),
110 Token::MapEnd,
111 ],
112 )
113 }
114
115 #[test]
116 fn item_set_value_on_long() {
117 assert_ser_tokens(
118 &item(SetValue::On(ClickDuration::Long)),
119 &[
120 Token::Map { len: None },
121 Token::Str("STATE"),
122 Token::Str("ON"),
123 Token::Str("LONG_CLICK"),
124 Token::Str("ON"),
125 Token::Str("NUMBER"),
126 Token::U32(1),
127 Token::MapEnd,
128 ],
129 )
130 }
131
132 #[test]
133 fn item_set_value_off_long() {
134 assert_ser_tokens(
135 &item(SetValue::Off(ClickDuration::Long)),
136 &[
137 Token::Map { len: None },
138 Token::Str("STATE"),
139 Token::Str("OFF"),
140 Token::Str("LONG_CLICK"),
141 Token::Str("ON"),
142 Token::Str("NUMBER"),
143 Token::U32(1),
144 Token::MapEnd,
145 ],
146 )
147 }
148
149 #[test]
150 fn item_set_value_dim() {
151 assert_ser_tokens(
152 &item(SetValue::Dimm(50)),
153 &[
154 Token::Map { len: None },
155 Token::Str("STATE"),
156 Token::Str("VALUE_DIMM"),
157 Token::Str("VALUE"),
158 Token::U8(50),
159 Token::Str("NUMBER"),
160 Token::U32(1),
161 Token::MapEnd,
162 ],
163 )
164 }
165
166 #[test]
167 fn item_set_value_blinds() {
168 assert_ser_tokens(
169 &item(SetValue::Blinds(50)),
170 &[
171 Token::Map { len: None },
172 Token::Str("STATE"),
173 Token::Str("VALUE_BLINDS"),
174 Token::Str("VALUE"),
175 Token::U8(50),
176 Token::Str("NUMBER"),
177 Token::U32(1),
178 Token::MapEnd,
179 ],
180 )
181 }
182}