1use serde::de::value::{MapDeserializer, SeqDeserializer};
2
3tonic::include_proto!("boardswarm");
4
5pub const DEFAULT_PORT: u16 = 6683;
7
8#[derive(Clone, Default, Debug, PartialEq)]
9pub struct Parameters(prost_types::Struct);
10
11impl Parameters {
12 pub fn insert(&mut self, k: String, v: ParamValue) {
13 self.0.fields.insert(k, v.0);
14 }
15}
16
17impl prost::Message for Parameters {
18 fn encode_raw<B>(&self, buf: &mut B)
19 where
20 B: bytes::BufMut,
21 Self: Sized,
22 {
23 self.0.encode_raw(buf)
24 }
25
26 fn merge_field<B>(
27 &mut self,
28 tag: u32,
29 wire_type: prost::encoding::WireType,
30 buf: &mut B,
31 ctx: prost::encoding::DecodeContext,
32 ) -> Result<(), prost::DecodeError>
33 where
34 B: bytes::Buf,
35 Self: Sized,
36 {
37 self.0.merge_field(tag, wire_type, buf, ctx)
38 }
39
40 fn encoded_len(&self) -> usize {
41 self.0.encoded_len()
42 }
43
44 fn clear(&mut self) {
45 self.0.clear()
46 }
47}
48
49macro_rules! value_visit_num {
50 ($ty:ident : $visit:ident) => {
51 fn $visit<E>(self, v: $ty) -> Result<Self::Value, E>
52 where
53 E: serde::de::Error,
54 {
55 Ok(ParamValue::from(v as f64))
56 }
57 };
58}
59
60pub struct ParamValue(prost_types::Value);
61impl From<&str> for ParamValue {
62 fn from(s: &str) -> ParamValue {
63 ParamValue::from(s.to_string())
64 }
65}
66
67impl From<String> for ParamValue {
68 fn from(s: String) -> ParamValue {
69 ParamValue(prost_types::Value {
70 kind: Some(prost_types::value::Kind::StringValue(s)),
71 })
72 }
73}
74
75impl From<f64> for ParamValue {
76 fn from(v: f64) -> ParamValue {
77 ParamValue(prost_types::Value {
78 kind: Some(prost_types::value::Kind::NumberValue(v)),
79 })
80 }
81}
82
83impl From<bool> for ParamValue {
84 fn from(b: bool) -> ParamValue {
85 ParamValue(prost_types::Value {
86 kind: Some(prost_types::value::Kind::BoolValue(b)),
87 })
88 }
89}
90
91impl From<prost_types::Struct> for ParamValue {
92 fn from(s: prost_types::Struct) -> ParamValue {
93 ParamValue(prost_types::Value {
94 kind: Some(prost_types::value::Kind::StructValue(s)),
95 })
96 }
97}
98
99impl From<Parameters> for ParamValue {
100 fn from(p: Parameters) -> ParamValue {
101 ParamValue::from(p.0)
102 }
103}
104
105impl From<Vec<prost_types::Value>> for ParamValue {
106 fn from(values: Vec<prost_types::Value>) -> ParamValue {
107 ParamValue(prost_types::Value {
108 kind: Some(prost_types::value::Kind::ListValue(
109 prost_types::ListValue { values },
110 )),
111 })
112 }
113}
114
115impl From<Vec<ParamValue>> for ParamValue {
116 fn from(mut values: Vec<ParamValue>) -> ParamValue {
117 let values: Vec<_> = values.drain(..).map(|v| v.0).collect();
118 ParamValue::from(values)
119 }
120}
121
122impl<'de> serde::Deserialize<'de> for ParamValue {
123 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
124 where
125 D: serde::Deserializer<'de>,
126 {
127 struct ValueVisitor {}
128 impl<'de> serde::de::Visitor<'de> for ValueVisitor {
129 type Value = ParamValue;
130
131 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
132 formatter.write_str("a value")
133 }
134
135 value_visit_num!(u8: visit_u8);
136 value_visit_num!(u16: visit_u16);
137 value_visit_num!(u32: visit_u32);
138 value_visit_num!(u64: visit_u64);
139
140 value_visit_num!(i8: visit_i8);
141 value_visit_num!(i16: visit_i16);
142 value_visit_num!(i32: visit_i32);
143 value_visit_num!(i64: visit_i64);
144
145 value_visit_num!(f32: visit_f32);
146 value_visit_num!(f64: visit_f64);
147
148 fn visit_bool<E>(self, b: bool) -> Result<Self::Value, E>
149 where
150 E: serde::de::Error,
151 {
152 Ok(ParamValue::from(b))
153 }
154
155 fn visit_str<E>(self, v: &str) -> Result<Self::Value, E>
156 where
157 E: serde::de::Error,
158 {
159 Ok(ParamValue::from(v))
160 }
161
162 fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
163 where
164 E: serde::de::Error,
165 {
166 Ok(ParamValue::from(v))
167 }
168
169 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
170 where
171 A: serde::de::MapAccess<'de>,
172 {
173 let mut parameter = Parameters::default();
174 while let Some((key, value)) = map.next_entry()? {
175 parameter.insert(key, value);
176 }
177
178 Ok(ParamValue::from(parameter))
179 }
180
181 fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
182 where
183 A: serde::de::SeqAccess<'de>,
184 {
185 let len = seq.size_hint().unwrap_or_default().min(4096);
186 let mut values = Vec::with_capacity(len);
187 while let Some(value) = seq.next_element::<ParamValue>()? {
188 values.push(value.0);
189 }
190
191 Ok(ParamValue::from(values))
192 }
193 }
194
195 let visitor = ValueVisitor {};
196 deserializer.deserialize_any(visitor)
197 }
198}
199
200impl<'de> serde::de::IntoDeserializer<'de, serde::de::value::Error> for ParamValue {
201 type Deserializer = Self;
202
203 fn into_deserializer(self) -> Self::Deserializer {
204 self
205 }
206}
207
208impl<'de> serde::Deserialize<'de> for Parameters {
209 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
210 where
211 D: serde::Deserializer<'de>,
212 {
213 struct StructVisitor {}
214 impl<'de> serde::de::Visitor<'de> for StructVisitor {
215 type Value = Parameters;
216
217 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
218 formatter.write_str("a map")
219 }
220
221 fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
222 where
223 A: serde::de::MapAccess<'de>,
224 {
225 let mut parameters = Parameters::default();
226 while let Some((key, value)) = map.next_entry()? {
227 parameters.insert(key, value);
228 }
229
230 Ok(parameters)
231 }
232 }
233
234 let visitor = StructVisitor {};
235 deserializer.deserialize_map(visitor)
236 }
237}
238
239impl<'de> serde::Deserializer<'de> for Parameters {
240 type Error = serde::de::value::Error;
241
242 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
243 where
244 V: serde::de::Visitor<'de>,
245 {
246 let deserializer =
247 MapDeserializer::new(self.0.fields.into_iter().map(|(k, v)| (k, ParamValue(v))));
248 let map = visitor.visit_map(deserializer)?;
249 Ok(map)
251 }
252
253 serde::forward_to_deserialize_any! {
254 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string
255 bytes byte_buf option unit unit_struct newtype_struct seq tuple
256 tuple_struct map struct enum identifier ignored_any
257 }
258}
259
260macro_rules! deserialize_number_as_int {
261 ($deserialize:ident:$visit:ident:$ty:ident) => {
262 fn $deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
263 where
264 V: serde::de::Visitor<'de>,
265 {
266 if let Some(prost_types::value::Kind::NumberValue(v)) = self.0.kind {
267 if v.fract() == 0.0 {
268 let v = v as i64;
269 if let Ok(v) = v.try_into() {
270 return visitor.$visit(v);
271 }
272 }
273 }
274 self.deserialize_any(visitor)
275 }
276 };
277}
278
279impl<'de> serde::Deserializer<'de> for ParamValue {
280 type Error = serde::de::value::Error;
281 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
282 where
283 V: serde::de::Visitor<'de>,
284 {
285 if let Some(v) = self.0.kind {
286 match v {
287 prost_types::value::Kind::NullValue(_) => visitor.visit_none(),
288 prost_types::value::Kind::NumberValue(v) => visitor.visit_f64(v),
289 prost_types::value::Kind::StringValue(s) => visitor.visit_string(s),
290 prost_types::value::Kind::BoolValue(b) => visitor.visit_bool(b),
291 prost_types::value::Kind::StructValue(p) => Parameters(p).deserialize_any(visitor),
292 prost_types::value::Kind::ListValue(list) => {
293 let seq = SeqDeserializer::new(list.values.into_iter().map(ParamValue));
294 visitor.visit_seq(seq)
295 }
296 }
297 } else {
298 visitor.visit_none()
299 }
300 }
301
302 deserialize_number_as_int!(deserialize_i8: visit_i8: i8);
315 deserialize_number_as_int!(deserialize_i16: visit_i16: i16);
316 deserialize_number_as_int!(deserialize_i32: visit_i32: i32);
317 deserialize_number_as_int!(deserialize_i64: visit_i64: i64);
318 deserialize_number_as_int!(deserialize_u8: visit_u8: u8);
319 deserialize_number_as_int!(deserialize_u16: visit_u16: u16);
320 deserialize_number_as_int!(deserialize_u32: visit_u32: u32);
321 deserialize_number_as_int!(deserialize_u64: visit_u64: u64);
322
323 serde::forward_to_deserialize_any! {
324 bool i128 u128 f32 f64 char str string
325 bytes byte_buf option unit unit_struct newtype_struct seq tuple
326 tuple_struct map struct enum identifier ignored_any
327 }
328}
329
330#[cfg(test)]
331mod test {
332 use serde::Deserialize;
333
334 use super::*;
335
336 #[test]
337 fn test_deserialize() {
338 let p: Parameters = serde_json::from_str(
339 r#"
340 {
341 "number": 115200,
342 "bool": true,
343 "string": "gnirts",
344 "list": [ "a", 2 ],
345 "struct": {
346 "number": 115200,
347 "bool": true,
348 "string": "gnirts",
349 "list": [ "a", 2 ]
350 }
351 }
352 "#,
353 )
354 .unwrap();
355 let mut expected = Parameters::default();
356 expected.insert("number".to_string(), ParamValue::from(115200_f64));
357 expected.insert("bool".to_string(), ParamValue::from(true));
358 expected.insert("string".to_string(), ParamValue::from("gnirts"));
359
360 let list = vec![ParamValue::from("a"), ParamValue::from(2f64)];
361 expected.insert("list".to_string(), ParamValue::from(list));
362
363 let subparameters = expected.clone();
364 expected.insert("struct".to_string(), ParamValue::from(subparameters));
365
366 assert_eq!(p, expected);
367 }
368
369 #[test]
370 fn test_deserializer() {
371 let mut data = Parameters::default();
372 data.insert("number".to_string(), ParamValue::from(115200_f64));
373 data.insert("bool".to_string(), ParamValue::from(true));
374 data.insert("string".to_string(), ParamValue::from("gnirts"));
375
376 let list = vec![ParamValue::from("a"), ParamValue::from("b")];
377 data.insert("list".to_string(), ParamValue::from(list));
378
379 let subparameters = data.clone();
380 data.insert("struct".to_string(), ParamValue::from(subparameters));
381
382 #[derive(Debug, PartialEq, Deserialize)]
383 struct Test {
384 number: f64,
385 string: String,
386 list: Vec<String>,
387 #[serde(rename = "struct")]
388 struct_: Test2,
389 }
390 #[derive(Debug, PartialEq, Deserialize)]
391 struct Test2 {
392 number: u32,
393 string: String,
394 list: Vec<String>,
395 }
396
397 let t = Test::deserialize(data).unwrap();
398 assert_eq!(
399 t,
400 Test {
401 number: 115200f64,
402 string: "gnirts".to_string(),
403 list: vec!["a".to_string(), "b".to_string()],
404 struct_: Test2 {
405 number: 115200,
406 string: "gnirts".to_string(),
407 list: vec!["a".to_string(), "b".to_string()]
408 }
409 }
410 );
411 }
412}