boardswarm_protocol/
lib.rs

1use serde::de::value::{MapDeserializer, SeqDeserializer};
2
3tonic::include_proto!("boardswarm");
4
5/// Default port for boardswarm servers
6pub 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        //deserializer.end()?;
250        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    /*
303    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value, Self::Error>
304    where
305        V: serde::de::Visitor<'de>,
306    {
307        if let Some(prost_types::value::Kind::NumberValue(v)) = self.0.kind {
308            visitor.visit_u32(v as u32)
309        } else {
310            self.deserialize_any(visitor)
311        }
312    }
313    */
314    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}