cu29_value/
lib.rs

1#![doc(html_root_url = "https://docs.rs/serde-value/0.7.0/")]
2
3use cu29_clock::CuTime;
4use ordered_float::OrderedFloat;
5use serde::Deserialize;
6use std::cmp::Ordering;
7use std::collections::BTreeMap;
8use std::fmt::{Display, Formatter};
9use std::hash::{Hash, Hasher};
10
11mod bdec;
12mod benc;
13mod de;
14mod ser;
15
16pub use de::*;
17pub use ser::*;
18
19#[derive(Clone, Debug)]
20pub enum Value {
21    Bool(bool),
22
23    U8(u8),
24    U16(u16),
25    U32(u32),
26    U64(u64),
27
28    I8(i8),
29    I16(i16),
30    I32(i32),
31    I64(i64),
32
33    F32(f32),
34    F64(f64),
35
36    Char(char),
37    String(String),
38    Unit,
39    Option(Option<Box<Value>>),
40    Newtype(Box<Value>),
41    Seq(Vec<Value>),
42    Map(BTreeMap<Value, Value>),
43    Bytes(Vec<u8>),
44
45    CuTime(CuTime),
46}
47
48impl Display for Value {
49    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
50        match self {
51            Value::Bool(v) => write!(f, "{}", v),
52            Value::U8(v) => write!(f, "{}", v),
53            Value::U16(v) => write!(f, "{}", v),
54            Value::U32(v) => write!(f, "{}", v),
55            Value::U64(v) => write!(f, "{}", v),
56            Value::I8(v) => write!(f, "{}", v),
57            Value::I16(v) => write!(f, "{}", v),
58            Value::I32(v) => write!(f, "{}", v),
59            Value::I64(v) => write!(f, "{}", v),
60            Value::F32(v) => write!(f, "{}", v),
61            Value::F64(v) => write!(f, "{}", v),
62            Value::Char(v) => write!(f, "{}", v),
63            Value::String(v) => write!(f, "{}", v),
64            Value::Unit => write!(f, "()"),
65            Value::Option(v) => match v {
66                Some(v) => write!(f, "Some({})", v),
67                None => write!(f, "None"),
68            },
69            Value::Newtype(v) => write!(f, "{}", v),
70            Value::Seq(v) => {
71                write!(f, "[")?;
72                for (i, v) in v.iter().enumerate() {
73                    if i > 0 {
74                        write!(f, ", ")?;
75                    }
76                    write!(f, "{}", v)?;
77                }
78                write!(f, "]")
79            }
80            Value::Map(v) => {
81                write!(f, "{{")?;
82                for (i, (k, v)) in v.iter().enumerate() {
83                    if i > 0 {
84                        write!(f, ", ")?;
85                    }
86                    write!(f, "{}: {}", k, v)?;
87                }
88                write!(f, "}}")
89            }
90            Value::Bytes(v) => {
91                write!(f, "[")?;
92                for (i, b) in v.iter().enumerate() {
93                    if i > 0 {
94                        write!(f, " ")?;
95                    }
96                    write!(f, "{:02x}", b)?;
97                }
98                write!(f, "]")
99            }
100            Value::CuTime(v) => write!(f, "{}", v),
101        }
102    }
103}
104
105impl Hash for Value {
106    fn hash<H>(&self, hasher: &mut H)
107    where
108        H: Hasher,
109    {
110        self.discriminant().hash(hasher);
111        match *self {
112            Value::Bool(v) => v.hash(hasher),
113            Value::U8(v) => v.hash(hasher),
114            Value::U16(v) => v.hash(hasher),
115            Value::U32(v) => v.hash(hasher),
116            Value::U64(v) => v.hash(hasher),
117            Value::I8(v) => v.hash(hasher),
118            Value::I16(v) => v.hash(hasher),
119            Value::I32(v) => v.hash(hasher),
120            Value::I64(v) => v.hash(hasher),
121            Value::F32(v) => OrderedFloat(v).hash(hasher),
122            Value::F64(v) => OrderedFloat(v).hash(hasher),
123            Value::Char(v) => v.hash(hasher),
124            Value::String(ref v) => v.hash(hasher),
125            Value::Unit => 0_u8.hash(hasher),
126            Value::Option(ref v) => v.hash(hasher),
127            Value::Newtype(ref v) => v.hash(hasher),
128            Value::Seq(ref v) => v.hash(hasher),
129            Value::Map(ref v) => v.hash(hasher),
130            Value::Bytes(ref v) => v.hash(hasher),
131            Value::CuTime(v) => v.0.hash(hasher),
132        }
133    }
134}
135
136impl PartialEq for Value {
137    fn eq(&self, rhs: &Self) -> bool {
138        match (self, rhs) {
139            (&Value::Bool(v0), &Value::Bool(v1)) if v0 == v1 => true,
140            (&Value::U8(v0), &Value::U8(v1)) if v0 == v1 => true,
141            (&Value::U16(v0), &Value::U16(v1)) if v0 == v1 => true,
142            (&Value::U32(v0), &Value::U32(v1)) if v0 == v1 => true,
143            (&Value::U64(v0), &Value::U64(v1)) if v0 == v1 => true,
144            (&Value::I8(v0), &Value::I8(v1)) if v0 == v1 => true,
145            (&Value::I16(v0), &Value::I16(v1)) if v0 == v1 => true,
146            (&Value::I32(v0), &Value::I32(v1)) if v0 == v1 => true,
147            (&Value::I64(v0), &Value::I64(v1)) if v0 == v1 => true,
148            (&Value::F32(v0), &Value::F32(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
149            (&Value::F64(v0), &Value::F64(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
150            (&Value::Char(v0), &Value::Char(v1)) if v0 == v1 => true,
151            (Value::String(v0), Value::String(v1)) if v0 == v1 => true,
152            (&Value::Unit, &Value::Unit) => true,
153            (Value::Option(v0), Value::Option(v1)) if v0 == v1 => true,
154            (Value::Newtype(v0), Value::Newtype(v1)) if v0 == v1 => true,
155            (Value::Seq(v0), Value::Seq(v1)) if v0 == v1 => true,
156            (Value::Map(v0), Value::Map(v1)) if v0 == v1 => true,
157            (Value::Bytes(v0), Value::Bytes(v1)) if v0 == v1 => true,
158            (&Value::CuTime(v0), &Value::CuTime(v1)) if v0 == v1 => true,
159            _ => false,
160        }
161    }
162}
163
164impl Ord for Value {
165    fn cmp(&self, rhs: &Self) -> Ordering {
166        match (self, rhs) {
167            (&Value::Bool(v0), Value::Bool(v1)) => v0.cmp(v1),
168            (&Value::U8(v0), Value::U8(v1)) => v0.cmp(v1),
169            (&Value::U16(v0), Value::U16(v1)) => v0.cmp(v1),
170            (&Value::U32(v0), Value::U32(v1)) => v0.cmp(v1),
171            (&Value::U64(v0), Value::U64(v1)) => v0.cmp(v1),
172            (&Value::I8(v0), Value::I8(v1)) => v0.cmp(v1),
173            (&Value::I16(v0), Value::I16(v1)) => v0.cmp(v1),
174            (&Value::I32(v0), Value::I32(v1)) => v0.cmp(v1),
175            (&Value::I64(v0), Value::I64(v1)) => v0.cmp(v1),
176            (&Value::F32(v0), &Value::F32(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
177            (&Value::F64(v0), &Value::F64(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
178            (&Value::Char(v0), Value::Char(v1)) => v0.cmp(v1),
179            (Value::String(v0), Value::String(v1)) => v0.cmp(v1),
180            (&Value::Unit, &Value::Unit) => Ordering::Equal,
181            (Value::Option(v0), Value::Option(v1)) => v0.cmp(v1),
182            (Value::Newtype(v0), Value::Newtype(v1)) => v0.cmp(v1),
183            (Value::Seq(v0), Value::Seq(v1)) => v0.cmp(v1),
184            (Value::Map(v0), Value::Map(v1)) => v0.cmp(v1),
185            (Value::Bytes(v0), Value::Bytes(v1)) => v0.cmp(v1),
186            (&Value::CuTime(v0), &Value::CuTime(v1)) => v0.cmp(&v1),
187            (v0, v1) => v0.discriminant().cmp(&v1.discriminant()),
188        }
189    }
190}
191
192impl Value {
193    fn discriminant(&self) -> usize {
194        match *self {
195            Value::Bool(..) => 0,
196            Value::U8(..) => 1,
197            Value::U16(..) => 2,
198            Value::U32(..) => 3,
199            Value::U64(..) => 4,
200            Value::I8(..) => 5,
201            Value::I16(..) => 6,
202            Value::I32(..) => 7,
203            Value::I64(..) => 8,
204            Value::F32(..) => 9,
205            Value::F64(..) => 10,
206            Value::Char(..) => 11,
207            Value::String(..) => 12,
208            Value::Unit => 13,
209            Value::Option(..) => 14,
210            Value::Newtype(..) => 15,
211            Value::Seq(..) => 16,
212            Value::Map(..) => 17,
213            Value::Bytes(..) => 18,
214            Value::CuTime(..) => 32,
215        }
216    }
217
218    fn unexpected(&self) -> serde::de::Unexpected {
219        match *self {
220            Value::Bool(b) => serde::de::Unexpected::Bool(b),
221            Value::U8(n) => serde::de::Unexpected::Unsigned(n as u64),
222            Value::U16(n) => serde::de::Unexpected::Unsigned(n as u64),
223            Value::U32(n) => serde::de::Unexpected::Unsigned(n as u64),
224            Value::U64(n) => serde::de::Unexpected::Unsigned(n),
225            Value::I8(n) => serde::de::Unexpected::Signed(n as i64),
226            Value::I16(n) => serde::de::Unexpected::Signed(n as i64),
227            Value::I32(n) => serde::de::Unexpected::Signed(n as i64),
228            Value::I64(n) => serde::de::Unexpected::Signed(n),
229            Value::F32(n) => serde::de::Unexpected::Float(n as f64),
230            Value::F64(n) => serde::de::Unexpected::Float(n),
231            Value::Char(c) => serde::de::Unexpected::Char(c),
232            Value::String(ref s) => serde::de::Unexpected::Str(s),
233            Value::Unit => serde::de::Unexpected::Unit,
234            Value::Option(_) => serde::de::Unexpected::Option,
235            Value::Newtype(_) => serde::de::Unexpected::NewtypeStruct,
236            Value::Seq(_) => serde::de::Unexpected::Seq,
237            Value::Map(_) => serde::de::Unexpected::Map,
238            Value::Bytes(ref b) => serde::de::Unexpected::Bytes(b),
239            Value::CuTime(n) => serde::de::Unexpected::Unsigned(n.0),
240        }
241    }
242
243    pub fn deserialize_into<'de, T: Deserialize<'de>>(self) -> Result<T, DeserializerError> {
244        T::deserialize(self)
245    }
246}
247
248impl Eq for Value {}
249impl PartialOrd for Value {
250    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
251        Some(self.cmp(rhs))
252    }
253}
254
255#[cfg(test)]
256mod tests {
257    use super::*;
258    use bincode::config::standard;
259    use cu29_clock::RobotClock;
260    use serde_derive::{Deserialize, Serialize};
261    use std::time::Duration;
262
263    #[test]
264    fn de_smoke_test() {
265        // some convoluted Value
266        let value = Value::Option(Some(Box::new(Value::Seq(vec![
267            Value::U16(8),
268            Value::Char('a'),
269            Value::F32(1.0),
270            Value::String("hello".into()),
271            Value::Map(
272                vec![
273                    (Value::Bool(false), Value::Unit),
274                    (
275                        Value::Bool(true),
276                        Value::Newtype(Box::new(Value::Bytes(b"hi".as_ref().into()))),
277                    ),
278                ]
279                .into_iter()
280                .collect(),
281            ),
282        ]))));
283
284        // assert that the value remains unchanged through deserialization
285        let value_de = Value::deserialize(value.clone()).unwrap();
286        assert_eq!(value_de, value);
287    }
288
289    #[test]
290    fn ser_smoke_test() {
291        #[derive(Serialize)]
292        struct Foo {
293            a: u32,
294            b: String,
295            c: Vec<bool>,
296        }
297
298        let foo = Foo {
299            a: 15,
300            b: "hello".into(),
301            c: vec![true, false],
302        };
303
304        let expected = Value::Map(
305            vec![
306                (Value::String("a".into()), Value::U32(15)),
307                (Value::String("b".into()), Value::String("hello".into())),
308                (
309                    Value::String("c".into()),
310                    Value::Seq(vec![Value::Bool(true), Value::Bool(false)]),
311                ),
312            ]
313            .into_iter()
314            .collect(),
315        );
316
317        let value = to_value(&foo).unwrap();
318        assert_eq!(expected, value);
319    }
320
321    #[test]
322    fn deserialize_into_enum() {
323        #[derive(Deserialize, Debug, PartialEq, Eq)]
324        enum Foo {
325            Bar,
326            Baz(u8),
327        }
328
329        let value = Value::String("Bar".into());
330        assert_eq!(Foo::deserialize(value).unwrap(), Foo::Bar);
331
332        let value = Value::Map(
333            vec![(Value::String("Baz".into()), Value::U8(1))]
334                .into_iter()
335                .collect(),
336        );
337        assert_eq!(Foo::deserialize(value).unwrap(), Foo::Baz(1));
338    }
339
340    #[test]
341    fn serialize_from_enum() {
342        #[derive(Serialize)]
343        enum Foo {
344            Bar,
345            Baz(u8),
346            Qux { quux: u8 },
347            Corge(u8, u8),
348        }
349
350        let bar = Foo::Bar;
351        assert_eq!(to_value(&bar).unwrap(), Value::String("Bar".into()));
352
353        let baz = Foo::Baz(1);
354        assert_eq!(
355            to_value(&baz).unwrap(),
356            Value::Map(
357                vec![(Value::String("Baz".into()), Value::U8(1))]
358                    .into_iter()
359                    .collect(),
360            )
361        );
362
363        let qux = Foo::Qux { quux: 2 };
364        assert_eq!(
365            to_value(&qux).unwrap(),
366            Value::Map(
367                vec![(
368                    Value::String("Qux".into()),
369                    Value::Map(
370                        vec![(Value::String("quux".into()), Value::U8(2))]
371                            .into_iter()
372                            .collect()
373                    )
374                )]
375                .into_iter()
376                .collect()
377            )
378        );
379
380        let corge = Foo::Corge(3, 4);
381        assert_eq!(
382            to_value(&corge).unwrap(),
383            Value::Map(
384                vec![(
385                    Value::String("Corge".into()),
386                    Value::Seq(vec![Value::U8(3), Value::U8(4)])
387                )]
388                .into_iter()
389                .collect()
390            )
391        );
392    }
393
394    #[test]
395    fn deserialize_inside_deserialize_impl() {
396        #[derive(Debug, PartialEq, Eq)]
397        enum Event {
398            Added(u32),
399            Error(u8),
400        }
401
402        impl<'de> serde::Deserialize<'de> for Event {
403            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
404            where
405                D: serde::Deserializer<'de>,
406            {
407                #[derive(Deserialize)]
408                struct RawEvent {
409                    kind: String,
410                    object: Value,
411                }
412
413                let raw_event = RawEvent::deserialize(deserializer)?;
414
415                // Cannot directly use Value as Deserializer, since error type needs to be
416                // generic D::Error rather than specific serde_value::DeserializerError
417                let object_deserializer = ValueDeserializer::new(raw_event.object);
418
419                Ok(match &*raw_event.kind {
420                    "ADDED" => Event::Added(<_>::deserialize(object_deserializer)?),
421                    "ERROR" => Event::Error(<_>::deserialize(object_deserializer)?),
422                    kind => {
423                        return Err(serde::de::Error::unknown_variant(kind, &["ADDED", "ERROR"]))
424                    }
425                })
426            }
427        }
428
429        let input = Value::Map(
430            vec![
431                (
432                    Value::String("kind".to_owned()),
433                    Value::String("ADDED".to_owned()),
434                ),
435                (Value::String("object".to_owned()), Value::U32(5)),
436            ]
437            .into_iter()
438            .collect(),
439        );
440        let event = Event::deserialize(input).expect("could not deserialize ADDED event");
441        assert_eq!(event, Event::Added(5));
442
443        let input = Value::Map(
444            vec![
445                (
446                    Value::String("kind".to_owned()),
447                    Value::String("ERROR".to_owned()),
448                ),
449                (Value::String("object".to_owned()), Value::U8(5)),
450            ]
451            .into_iter()
452            .collect(),
453        );
454        let event = Event::deserialize(input).expect("could not deserialize ERROR event");
455        assert_eq!(event, Event::Error(5));
456
457        let input = Value::Map(
458            vec![
459                (
460                    Value::String("kind".to_owned()),
461                    Value::String("ADDED".to_owned()),
462                ),
463                (Value::String("object".to_owned()), Value::Unit),
464            ]
465            .into_iter()
466            .collect(),
467        );
468        let _ =
469            Event::deserialize(input).expect_err("expected deserializing bad ADDED event to fail");
470    }
471
472    #[test]
473    fn deserialize_newtype() {
474        #[derive(Debug, Deserialize, PartialEq)]
475        struct Foo(i32);
476
477        let input = Value::I32(5);
478        let foo = Foo::deserialize(input).unwrap();
479        assert_eq!(foo, Foo(5));
480    }
481
482    #[test]
483    fn deserialize_newtype2() {
484        #[derive(Debug, Deserialize, PartialEq)]
485        struct Foo(i32);
486
487        #[derive(Debug, Deserialize, PartialEq)]
488        struct Bar {
489            foo: Foo,
490        }
491
492        let input = Value::Map(
493            vec![(Value::String("foo".to_owned()), Value::I32(5))]
494                .into_iter()
495                .collect(),
496        );
497        let bar = Bar::deserialize(input).unwrap();
498        assert_eq!(bar, Bar { foo: Foo(5) });
499    }
500
501    #[test]
502    fn clock_ser_deser() {
503        let (clock, mock) = RobotClock::mock();
504        mock.increment(Duration::from_nanos(42));
505        let c = clock.now();
506
507        let input = Value::CuTime(c);
508        let foo = CuTime::deserialize(input).unwrap();
509        assert_eq!(foo, CuTime::from(Duration::from_nanos(42)));
510    }
511    #[test]
512    fn value_encode_decode() {
513        fn check_value(value: Value) {
514            let v = bincode::encode_to_vec(&value, standard()).expect("encode failed");
515            let (v2, s) = bincode::decode_from_slice::<Value, _>(v.as_slice(), standard())
516                .expect("decode failed");
517            assert_eq!(s, v.len());
518            assert_eq!(&v2, &value);
519        }
520
521        check_value(Value::Bool(true));
522        check_value(Value::U8(42));
523        check_value(Value::U16(42));
524        check_value(Value::U32(42));
525        check_value(Value::U64(42));
526        check_value(Value::I8(42));
527        check_value(Value::I16(42));
528        check_value(Value::I32(42));
529        check_value(Value::I64(42));
530        check_value(Value::F32(42.42));
531        check_value(Value::F64(42.42));
532        check_value(Value::Char('4'));
533        check_value(Value::String("42".into()));
534        check_value(Value::Unit);
535        check_value(Value::Option(Some(Box::new(Value::U32(42)))));
536        check_value(Value::Newtype(Box::new(Value::U32(42))));
537        check_value(Value::Seq(vec![Value::Bool(true), Value::U32(42)]));
538        check_value(Value::Map(BTreeMap::from([
539            (Value::Bool(true), Value::U32(42)),
540            (Value::String("42".into()), Value::I32(42)),
541        ])));
542        check_value(Value::Bytes(vec![0x4, 0x2]));
543        check_value(Value::CuTime(CuTime::from(Duration::from_nanos(42))));
544    }
545
546    #[test]
547    fn test_cutime_tovalue() {
548        let c = CuTime::from(Duration::from_nanos(42));
549        let v = to_value(c).expect("to_value failed");
550        assert_eq!(v, Value::CuTime(c));
551    }
552}