cu29_value/
lib.rs

1#![doc(html_root_url = "https://docs.rs/serde-value/0.7.0/")]
2
3use cu29_clock::{CuDuration, 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, "{b:02x}")?;
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) => {
132                let CuDuration(nanos) = v;
133                nanos.hash(hasher)
134            }
135        }
136    }
137}
138
139impl PartialEq for Value {
140    fn eq(&self, rhs: &Self) -> bool {
141        match (self, rhs) {
142            (&Value::Bool(v0), &Value::Bool(v1)) if v0 == v1 => true,
143            (&Value::U8(v0), &Value::U8(v1)) if v0 == v1 => true,
144            (&Value::U16(v0), &Value::U16(v1)) if v0 == v1 => true,
145            (&Value::U32(v0), &Value::U32(v1)) if v0 == v1 => true,
146            (&Value::U64(v0), &Value::U64(v1)) if v0 == v1 => true,
147            (&Value::I8(v0), &Value::I8(v1)) if v0 == v1 => true,
148            (&Value::I16(v0), &Value::I16(v1)) if v0 == v1 => true,
149            (&Value::I32(v0), &Value::I32(v1)) if v0 == v1 => true,
150            (&Value::I64(v0), &Value::I64(v1)) if v0 == v1 => true,
151            (&Value::F32(v0), &Value::F32(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
152            (&Value::F64(v0), &Value::F64(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
153            (&Value::Char(v0), &Value::Char(v1)) if v0 == v1 => true,
154            (Value::String(v0), Value::String(v1)) if v0 == v1 => true,
155            (&Value::Unit, &Value::Unit) => true,
156            (Value::Option(v0), Value::Option(v1)) if v0 == v1 => true,
157            (Value::Newtype(v0), Value::Newtype(v1)) if v0 == v1 => true,
158            (Value::Seq(v0), Value::Seq(v1)) if v0 == v1 => true,
159            (Value::Map(v0), Value::Map(v1)) if v0 == v1 => true,
160            (Value::Bytes(v0), Value::Bytes(v1)) if v0 == v1 => true,
161            (&Value::CuTime(v0), &Value::CuTime(v1)) if v0 == v1 => true,
162            _ => false,
163        }
164    }
165}
166
167impl Ord for Value {
168    fn cmp(&self, rhs: &Self) -> Ordering {
169        match (self, rhs) {
170            (&Value::Bool(v0), Value::Bool(v1)) => v0.cmp(v1),
171            (&Value::U8(v0), Value::U8(v1)) => v0.cmp(v1),
172            (&Value::U16(v0), Value::U16(v1)) => v0.cmp(v1),
173            (&Value::U32(v0), Value::U32(v1)) => v0.cmp(v1),
174            (&Value::U64(v0), Value::U64(v1)) => v0.cmp(v1),
175            (&Value::I8(v0), Value::I8(v1)) => v0.cmp(v1),
176            (&Value::I16(v0), Value::I16(v1)) => v0.cmp(v1),
177            (&Value::I32(v0), Value::I32(v1)) => v0.cmp(v1),
178            (&Value::I64(v0), Value::I64(v1)) => v0.cmp(v1),
179            (&Value::F32(v0), &Value::F32(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
180            (&Value::F64(v0), &Value::F64(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
181            (&Value::Char(v0), Value::Char(v1)) => v0.cmp(v1),
182            (Value::String(v0), Value::String(v1)) => v0.cmp(v1),
183            (&Value::Unit, &Value::Unit) => Ordering::Equal,
184            (Value::Option(v0), Value::Option(v1)) => v0.cmp(v1),
185            (Value::Newtype(v0), Value::Newtype(v1)) => v0.cmp(v1),
186            (Value::Seq(v0), Value::Seq(v1)) => v0.cmp(v1),
187            (Value::Map(v0), Value::Map(v1)) => v0.cmp(v1),
188            (Value::Bytes(v0), Value::Bytes(v1)) => v0.cmp(v1),
189            (&Value::CuTime(v0), &Value::CuTime(v1)) => v0.cmp(&v1),
190            (v0, v1) => v0.discriminant().cmp(&v1.discriminant()),
191        }
192    }
193}
194
195impl Value {
196    fn discriminant(&self) -> usize {
197        match *self {
198            Value::Bool(..) => 0,
199            Value::U8(..) => 1,
200            Value::U16(..) => 2,
201            Value::U32(..) => 3,
202            Value::U64(..) => 4,
203            Value::I8(..) => 5,
204            Value::I16(..) => 6,
205            Value::I32(..) => 7,
206            Value::I64(..) => 8,
207            Value::F32(..) => 9,
208            Value::F64(..) => 10,
209            Value::Char(..) => 11,
210            Value::String(..) => 12,
211            Value::Unit => 13,
212            Value::Option(..) => 14,
213            Value::Newtype(..) => 15,
214            Value::Seq(..) => 16,
215            Value::Map(..) => 17,
216            Value::Bytes(..) => 18,
217            Value::CuTime(..) => 32,
218        }
219    }
220
221    fn unexpected(&self) -> serde::de::Unexpected<'_> {
222        match *self {
223            Value::Bool(b) => serde::de::Unexpected::Bool(b),
224            Value::U8(n) => serde::de::Unexpected::Unsigned(n as u64),
225            Value::U16(n) => serde::de::Unexpected::Unsigned(n as u64),
226            Value::U32(n) => serde::de::Unexpected::Unsigned(n as u64),
227            Value::U64(n) => serde::de::Unexpected::Unsigned(n),
228            Value::I8(n) => serde::de::Unexpected::Signed(n as i64),
229            Value::I16(n) => serde::de::Unexpected::Signed(n as i64),
230            Value::I32(n) => serde::de::Unexpected::Signed(n as i64),
231            Value::I64(n) => serde::de::Unexpected::Signed(n),
232            Value::F32(n) => serde::de::Unexpected::Float(n as f64),
233            Value::F64(n) => serde::de::Unexpected::Float(n),
234            Value::Char(c) => serde::de::Unexpected::Char(c),
235            Value::String(ref s) => serde::de::Unexpected::Str(s),
236            Value::Unit => serde::de::Unexpected::Unit,
237            Value::Option(_) => serde::de::Unexpected::Option,
238            Value::Newtype(_) => serde::de::Unexpected::NewtypeStruct,
239            Value::Seq(_) => serde::de::Unexpected::Seq,
240            Value::Map(_) => serde::de::Unexpected::Map,
241            Value::Bytes(ref b) => serde::de::Unexpected::Bytes(b),
242            Value::CuTime(n) => {
243                let CuDuration(nanos) = n;
244                serde::de::Unexpected::Unsigned(nanos)
245            }
246        }
247    }
248
249    pub fn deserialize_into<'de, T: Deserialize<'de>>(self) -> Result<T, DeserializerError> {
250        T::deserialize(self)
251    }
252}
253
254impl Eq for Value {}
255impl PartialOrd for Value {
256    fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
257        Some(self.cmp(rhs))
258    }
259}
260
261#[cfg(test)]
262mod tests {
263    use super::*;
264    use bincode::{config::standard, decode_from_slice, encode_to_vec};
265    use cu29_clock::{CuDuration, CuTime, RobotClock};
266    use serde_derive::{Deserialize, Serialize};
267    use std::collections::{hash_map::DefaultHasher, BTreeMap};
268    use std::hash::{Hash, Hasher};
269    use std::time::Duration;
270
271    #[test]
272    fn de_smoke_test() {
273        // some convoluted Value
274        let value = Value::Option(Some(Box::new(Value::Seq(vec![
275            Value::U16(8),
276            Value::Char('a'),
277            Value::F32(1.0),
278            Value::String("hello".into()),
279            Value::Map(
280                vec![
281                    (Value::Bool(false), Value::Unit),
282                    (
283                        Value::Bool(true),
284                        Value::Newtype(Box::new(Value::Bytes(b"hi".as_ref().into()))),
285                    ),
286                ]
287                .into_iter()
288                .collect(),
289            ),
290        ]))));
291
292        // assert that the value remains unchanged through deserialization
293        let value_de = Value::deserialize(value.clone()).unwrap();
294        assert_eq!(value_de, value);
295    }
296
297    #[test]
298    fn ser_smoke_test() {
299        #[derive(Serialize)]
300        struct Foo {
301            a: u32,
302            b: String,
303            c: Vec<bool>,
304        }
305
306        let foo = Foo {
307            a: 15,
308            b: "hello".into(),
309            c: vec![true, false],
310        };
311
312        let expected = Value::Map(
313            vec![
314                (Value::String("a".into()), Value::U32(15)),
315                (Value::String("b".into()), Value::String("hello".into())),
316                (
317                    Value::String("c".into()),
318                    Value::Seq(vec![Value::Bool(true), Value::Bool(false)]),
319                ),
320            ]
321            .into_iter()
322            .collect(),
323        );
324
325        let value = to_value(&foo).unwrap();
326        assert_eq!(expected, value);
327    }
328
329    #[test]
330    fn deserialize_into_enum() {
331        #[derive(Deserialize, Debug, PartialEq, Eq)]
332        enum Foo {
333            Bar,
334            Baz(u8),
335        }
336
337        let value = Value::String("Bar".into());
338        assert_eq!(Foo::deserialize(value).unwrap(), Foo::Bar);
339
340        let value = Value::Map(
341            vec![(Value::String("Baz".into()), Value::U8(1))]
342                .into_iter()
343                .collect(),
344        );
345        assert_eq!(Foo::deserialize(value).unwrap(), Foo::Baz(1));
346    }
347
348    #[test]
349    fn serialize_from_enum() {
350        #[derive(Serialize)]
351        enum Foo {
352            Bar,
353            Baz(u8),
354            Qux { quux: u8 },
355            Corge(u8, u8),
356        }
357
358        let bar = Foo::Bar;
359        assert_eq!(to_value(&bar).unwrap(), Value::String("Bar".into()));
360
361        let baz = Foo::Baz(1);
362        assert_eq!(
363            to_value(&baz).unwrap(),
364            Value::Map(
365                vec![(Value::String("Baz".into()), Value::U8(1))]
366                    .into_iter()
367                    .collect(),
368            )
369        );
370
371        let qux = Foo::Qux { quux: 2 };
372        assert_eq!(
373            to_value(&qux).unwrap(),
374            Value::Map(
375                vec![(
376                    Value::String("Qux".into()),
377                    Value::Map(
378                        vec![(Value::String("quux".into()), Value::U8(2))]
379                            .into_iter()
380                            .collect()
381                    )
382                )]
383                .into_iter()
384                .collect()
385            )
386        );
387
388        let corge = Foo::Corge(3, 4);
389        assert_eq!(
390            to_value(&corge).unwrap(),
391            Value::Map(
392                vec![(
393                    Value::String("Corge".into()),
394                    Value::Seq(vec![Value::U8(3), Value::U8(4)])
395                )]
396                .into_iter()
397                .collect()
398            )
399        );
400    }
401
402    #[test]
403    fn deserialize_inside_deserialize_impl() {
404        #[derive(Debug, PartialEq, Eq)]
405        enum Event {
406            Added(u32),
407            Error(u8),
408        }
409
410        impl<'de> serde::Deserialize<'de> for Event {
411            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
412            where
413                D: serde::Deserializer<'de>,
414            {
415                #[derive(Deserialize)]
416                struct RawEvent {
417                    kind: String,
418                    object: Value,
419                }
420
421                let raw_event = RawEvent::deserialize(deserializer)?;
422
423                // Cannot directly use Value as Deserializer, since error type needs to be
424                // generic D::Error rather than specific serde_value::DeserializerError
425                let object_deserializer = ValueDeserializer::new(raw_event.object);
426
427                Ok(match &*raw_event.kind {
428                    "ADDED" => Event::Added(<_>::deserialize(object_deserializer)?),
429                    "ERROR" => Event::Error(<_>::deserialize(object_deserializer)?),
430                    kind => {
431                        return Err(serde::de::Error::unknown_variant(kind, &["ADDED", "ERROR"]))
432                    }
433                })
434            }
435        }
436
437        let input = Value::Map(
438            vec![
439                (
440                    Value::String("kind".to_owned()),
441                    Value::String("ADDED".to_owned()),
442                ),
443                (Value::String("object".to_owned()), Value::U32(5)),
444            ]
445            .into_iter()
446            .collect(),
447        );
448        let event = Event::deserialize(input).expect("could not deserialize ADDED event");
449        assert_eq!(event, Event::Added(5));
450
451        let input = Value::Map(
452            vec![
453                (
454                    Value::String("kind".to_owned()),
455                    Value::String("ERROR".to_owned()),
456                ),
457                (Value::String("object".to_owned()), Value::U8(5)),
458            ]
459            .into_iter()
460            .collect(),
461        );
462        let event = Event::deserialize(input).expect("could not deserialize ERROR event");
463        assert_eq!(event, Event::Error(5));
464
465        let input = Value::Map(
466            vec![
467                (
468                    Value::String("kind".to_owned()),
469                    Value::String("ADDED".to_owned()),
470                ),
471                (Value::String("object".to_owned()), Value::Unit),
472            ]
473            .into_iter()
474            .collect(),
475        );
476        let _ =
477            Event::deserialize(input).expect_err("expected deserializing bad ADDED event to fail");
478    }
479
480    #[test]
481    fn deserialize_newtype() {
482        #[derive(Debug, Deserialize, PartialEq)]
483        struct Foo(i32);
484
485        let input = Value::I32(5);
486        let foo = Foo::deserialize(input).unwrap();
487        assert_eq!(foo, Foo(5));
488    }
489
490    #[test]
491    fn deserialize_newtype2() {
492        #[derive(Debug, Deserialize, PartialEq)]
493        struct Foo(i32);
494
495        #[derive(Debug, Deserialize, PartialEq)]
496        struct Bar {
497            foo: Foo,
498        }
499
500        let input = Value::Map(
501            vec![(Value::String("foo".to_owned()), Value::I32(5))]
502                .into_iter()
503                .collect(),
504        );
505        let bar = Bar::deserialize(input).unwrap();
506        assert_eq!(bar, Bar { foo: Foo(5) });
507    }
508
509    #[test]
510    fn clock_ser_deser() {
511        let (clock, mock) = RobotClock::mock();
512        mock.increment(Duration::from_nanos(42));
513        let c = clock.now();
514
515        let input = Value::CuTime(c);
516        let foo = CuTime::deserialize(input).unwrap();
517        assert_eq!(foo, CuTime::from(Duration::from_nanos(42)));
518    }
519    #[test]
520    fn value_encode_decode() {
521        fn check_value(value: Value) {
522            let v = bincode::encode_to_vec(&value, standard()).expect("encode failed");
523            let (v2, s) = bincode::decode_from_slice::<Value, _>(v.as_slice(), standard())
524                .expect("decode failed");
525            assert_eq!(s, v.len());
526            assert_eq!(&v2, &value);
527        }
528
529        check_value(Value::Bool(true));
530        check_value(Value::U8(42));
531        check_value(Value::U16(42));
532        check_value(Value::U32(42));
533        check_value(Value::U64(42));
534        check_value(Value::I8(42));
535        check_value(Value::I16(42));
536        check_value(Value::I32(42));
537        check_value(Value::I64(42));
538        check_value(Value::F32(42.42));
539        check_value(Value::F64(42.42));
540        check_value(Value::Char('4'));
541        check_value(Value::String("42".into()));
542        check_value(Value::Unit);
543        check_value(Value::Option(Some(Box::new(Value::U32(42)))));
544        check_value(Value::Newtype(Box::new(Value::U32(42))));
545        check_value(Value::Seq(vec![Value::Bool(true), Value::U32(42)]));
546        check_value(Value::Map(BTreeMap::from([
547            (Value::Bool(true), Value::U32(42)),
548            (Value::String("42".into()), Value::I32(42)),
549        ])));
550        check_value(Value::Bytes(vec![0x4, 0x2]));
551        check_value(Value::CuTime(CuTime::from(Duration::from_nanos(42))));
552    }
553
554    #[test]
555    fn test_cutime_tovalue() {
556        let c = CuTime::from(Duration::from_nanos(42));
557        let v = to_value(c).expect("to_value failed");
558        assert_eq!(v, Value::CuTime(c));
559    }
560    /// Test basic value creation and type checking
561    #[test]
562    fn test_value_creation_and_types() {
563        // Create various value types
564        let bool_val = Value::Bool(true);
565        let i32_val = Value::I32(42);
566        let str_val = Value::String("test".to_string());
567        let unit_val = Value::Unit;
568        let option_val = Value::Option(Some(Box::new(Value::U8(5))));
569
570        // Verify type discrimination
571        assert!(matches!(bool_val, Value::Bool(true)));
572        assert!(matches!(i32_val, Value::I32(42)));
573        assert!(matches!(str_val, Value::String(ref s) if s == "test"));
574        assert!(matches!(unit_val, Value::Unit));
575        assert!(matches!(option_val, Value::Option(Some(_))));
576
577        // Check discriminant values
578        assert_eq!(bool_val.discriminant(), 0);
579        assert_eq!(i32_val.discriminant(), 7);
580        assert_eq!(str_val.discriminant(), 12);
581    }
582
583    /// Test numeric boundary values and special floating points
584    #[test]
585    fn test_numeric_boundaries_and_special_values() {
586        // Integer boundaries
587        let min_i8 = Value::I8(i8::MIN);
588        let max_i8 = Value::I8(i8::MAX);
589        let min_i64 = Value::I64(i64::MIN);
590        let max_u64 = Value::U64(u64::MAX);
591
592        // Special floating points
593        let nan = Value::F64(f64::NAN);
594        let pos_inf = Value::F64(f64::INFINITY);
595        let neg_inf = Value::F64(f64::NEG_INFINITY);
596        let zero = Value::F64(0.0);
597        let neg_zero = Value::F64(-0.0);
598
599        // Make sure these encode and decode correctly
600        for val in [
601            min_i8,
602            max_i8,
603            min_i64,
604            max_u64,
605            nan.clone(),
606            pos_inf.clone(),
607            neg_inf.clone(),
608            zero.clone(),
609            neg_zero.clone(),
610        ] {
611            let encoded = encode_to_vec(&val, standard()).unwrap();
612            let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
613
614            // Special case for NaN since NaN != NaN in normal floating point comparisons
615            if matches!(val, Value::F64(f) if f.is_nan()) {
616                assert!(matches!(decoded, Value::F64(f) if f.is_nan()));
617            } else {
618                assert_eq!(val, decoded);
619            }
620        }
621
622        // Test ordering behavior with special values
623        assert!(pos_inf > zero);
624        assert!(neg_inf < zero);
625
626        // NaN should be equal to itself when wrapped in Value (due to OrderedFloat)
627        let nan2 = Value::F64(f64::NAN);
628        assert_eq!(nan, nan2); // This works because Value uses OrderedFloat
629
630        // Verify zero and negative zero are treated as equal
631        assert_eq!(zero, neg_zero);
632    }
633
634    /// Test handling of containers (maps, sequences)
635    #[test]
636    fn test_container_types() {
637        // Empty containers
638        let empty_seq = Value::Seq(vec![]);
639        let empty_map = Value::Map(BTreeMap::new());
640
641        // Simple containers
642        let simple_seq = Value::Seq(vec![Value::I32(1), Value::I32(2), Value::I32(3)]);
643        let mut simple_map = BTreeMap::new();
644        simple_map.insert(Value::String("key".to_string()), Value::Bool(true));
645        let simple_map_val = Value::Map(simple_map);
646
647        // Deeply nested containers
648        let mut nested_map = BTreeMap::new();
649        nested_map.insert(
650            Value::String("outer".to_string()),
651            Value::Seq(vec![
652                Value::Option(Some(Box::new(Value::Map({
653                    let mut m = BTreeMap::new();
654                    m.insert(Value::I32(1), Value::String("nested".to_string()));
655                    m
656                })))),
657                Value::Bool(false),
658            ]),
659        );
660        let nested_val = Value::Map(nested_map);
661
662        // Encode and decode all container types
663        for val in [empty_seq, empty_map, simple_seq, simple_map_val, nested_val] {
664            let encoded = encode_to_vec(&val, standard()).unwrap();
665            let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
666            assert_eq!(val, decoded);
667        }
668    }
669
670    /// Test handling of large values
671    #[test]
672    fn test_large_values() {
673        // Large sequence
674        let large_seq = Value::Seq((0..10000).map(Value::I32).collect());
675
676        // Large string
677        let large_string = Value::String("x".repeat(100000));
678
679        // Large bytes
680        let large_bytes = Value::Bytes((0..10000).map(|i| (i % 256) as u8).collect());
681
682        // Large nested structure
683        let mut large_map = BTreeMap::new();
684        for i in 0..1000 {
685            large_map.insert(
686                Value::I32(i),
687                Value::Seq((0..10).map(|j| Value::I32(i * j)).collect()),
688            );
689        }
690        let large_nested = Value::Map(large_map);
691
692        // Test round-trip for large values
693        for val in [large_seq, large_string, large_bytes, large_nested] {
694            let encoded = encode_to_vec(&val, standard()).unwrap();
695            let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
696            assert_eq!(val, decoded);
697        }
698    }
699
700    /// Test value comparison across different types
701    #[test]
702    fn test_value_comparison() {
703        // Same type comparisons
704        assert!(Value::I32(1) < Value::I32(2));
705        assert!(Value::String("a".to_string()) < Value::String("b".to_string()));
706        assert!(Value::Bool(false) < Value::Bool(true));
707
708        // Different type comparisons (based on discriminant)
709        assert!(Value::Bool(true) < Value::I32(0)); // Bool(0) < I32(7) by discriminant
710        assert!(Value::I32(100) < Value::String("a".to_string())); // I32(7) < String(12)
711
712        // Container comparisons
713        assert!(
714            Value::Seq(vec![Value::I32(1), Value::I32(2)])
715                < Value::Seq(vec![Value::I32(1), Value::I32(3)])
716        );
717
718        let mut map1 = BTreeMap::new();
719        map1.insert(Value::String("key".to_string()), Value::I32(1));
720
721        let mut map2 = BTreeMap::new();
722        map2.insert(Value::String("key".to_string()), Value::I32(2));
723
724        assert!(Value::Map(map1) < Value::Map(map2));
725
726        // Test equality with NaN handling
727        let nan1 = Value::F64(f64::NAN);
728        let nan2 = Value::F64(f64::NAN);
729        assert_eq!(nan1, nan2); // OrderedFloat makes NaN == NaN
730    }
731
732    /// Test hash consistency for various value types
733    #[test]
734    fn test_value_hashing() {
735        let values = [
736            Value::Bool(true),
737            Value::I32(42),
738            Value::String("hash me".to_string()),
739            Value::F64(3.1),
740            Value::Char('🦀'),
741            Value::Option(Some(Box::new(Value::U8(5)))),
742            Value::Unit,
743        ];
744
745        for val in values {
746            // Hash the same value twice, should be consistent
747            let mut hasher1 = DefaultHasher::new();
748            let mut hasher2 = DefaultHasher::new();
749            val.hash(&mut hasher1);
750            val.hash(&mut hasher2);
751            assert_eq!(hasher1.finish(), hasher2.finish());
752
753            // Clone and hash, should be the same
754            let val_clone = val.clone();
755            let mut hasher3 = DefaultHasher::new();
756            val_clone.hash(&mut hasher3);
757            assert_eq!(hasher1.finish(), hasher3.finish());
758        }
759
760        // Special case: NaN should have consistent hash
761        let nan1 = Value::F64(f64::NAN);
762        let nan2 = Value::F64(f64::NAN);
763
764        let mut hasher1 = DefaultHasher::new();
765        let mut hasher2 = DefaultHasher::new();
766        nan1.hash(&mut hasher1);
767        nan2.hash(&mut hasher2);
768        assert_eq!(hasher1.finish(), hasher2.finish());
769    }
770
771    /// Test serialization/deserialization of custom data structures
772    #[test]
773    fn test_struct_serde() {
774        #[derive(Serialize, Deserialize, Debug, PartialEq)]
775        struct Person {
776            name: String,
777            age: u32,
778            addresses: Vec<Address>,
779        }
780
781        #[derive(Serialize, Deserialize, Debug, PartialEq)]
782        struct Address {
783            street: String,
784            city: String,
785            zip: u32,
786        }
787
788        let person = Person {
789            name: "Alice".to_string(),
790            age: 30,
791            addresses: vec![
792                Address {
793                    street: "123 Main St".to_string(),
794                    city: "Anytown".to_string(),
795                    zip: 12345,
796                },
797                Address {
798                    street: "456 Oak Ave".to_string(),
799                    city: "Somewhere".to_string(),
800                    zip: 67890,
801                },
802            ],
803        };
804
805        // Convert to Value
806        let value = to_value(&person).unwrap();
807
808        // Check structure
809        assert!(matches!(value, Value::Map(_)));
810
811        // Convert back to original type
812        let person2 = value.deserialize_into::<Person>().unwrap();
813        assert_eq!(person, person2);
814    }
815
816    /// Test enum serialization/deserialization
817    #[test]
818    fn test_enum_serde() {
819        #[derive(Serialize, Deserialize, Debug, PartialEq)]
820        enum MyEnum {
821            Unit,
822            NewType(i32),
823            Tuple(String, bool),
824            Struct { x: f64, y: f64 },
825        }
826
827        // Test all variants
828        let variants = vec![
829            MyEnum::Unit,
830            MyEnum::NewType(42),
831            MyEnum::Tuple("hello".to_string(), true),
832            MyEnum::Struct { x: 1.0, y: 2.0 },
833        ];
834
835        for variant in variants {
836            let value = to_value(&variant).unwrap();
837            let roundtrip = value.deserialize_into::<MyEnum>().unwrap();
838            assert_eq!(variant, roundtrip);
839        }
840    }
841
842    /// Test custom CuTime type handling
843    #[test]
844    fn test_cutime_handling() {
845        // Test round-trip for CuTime values
846        let times = vec![
847            CuTime::from(CuDuration(0)),
848            CuTime::from(CuDuration(1)),
849            CuTime::from(CuDuration(u64::MAX / 2)),
850            // Exclude MAX as it might be reserved for special use
851        ];
852
853        for time in times {
854            // Direct Value creation
855            let time_value = Value::CuTime(time);
856
857            // Serialize/deserialize as Value
858            let encoded = encode_to_vec(&time_value, standard()).unwrap();
859            let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
860            assert_eq!(time_value, decoded);
861
862            // Convert through to_value
863            let via_to_value = to_value(time).unwrap();
864            assert_eq!(via_to_value, time_value);
865
866            // Deserialize back to CuTime
867            let time_roundtrip = via_to_value.deserialize_into::<CuTime>().unwrap();
868            assert_eq!(time, time_roundtrip);
869        }
870    }
871
872    /// Test error handling in deserialization
873    #[test]
874    fn test_error_handling() {
875        // Type mismatch
876        let bool_val = Value::Bool(true);
877        let result = bool_val.clone().deserialize_into::<i32>();
878        assert!(result.is_err());
879
880        // Missing fields
881        let empty_map = Value::Map(BTreeMap::new());
882
883        #[derive(Deserialize)]
884        struct RequiredFields {
885            _required: String,
886        }
887
888        let result = empty_map.deserialize_into::<RequiredFields>();
889        assert!(result.is_err());
890
891        // Invalid enum variant
892        let invalid_variant = Value::String("NonExistentVariant".to_string());
893
894        #[derive(Deserialize)]
895        enum TestEnum {
896            A,
897            B,
898            C,
899        }
900
901        let result = invalid_variant.deserialize_into::<TestEnum>();
902        assert!(result.is_err());
903
904        // Check we get appropriate error types
905        match bool_val.deserialize_into::<String>() {
906            Err(DeserializerError::InvalidType(..)) => (), // Expected
907            other => panic!("Expected InvalidType error, got: {other:?}"),
908        }
909    }
910
911    /// Test unicode handling in strings and chars
912    #[test]
913    fn test_unicode_handling() {
914        let strings = vec![
915            "".to_string(),             // Empty
916            "ASCII only".to_string(),   // ASCII
917            "Café 🍰".to_string(),      // Mixed ASCII and Unicode
918            "日本語".to_string(),       // CJK characters
919            "👨‍👩‍👧‍👦 Family".to_string(),    // Complex emoji with ZWJ sequences
920            "ᛁᚲ ᚲᚨᚾ ᚱᚢᚾᛖᛋ".to_string(), // Ancient runes
921        ];
922
923        for s in strings {
924            let string_val = Value::String(s.clone());
925
926            // Test round-trip
927            let encoded = encode_to_vec(&string_val, standard()).unwrap();
928            let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
929
930            if let Value::String(decoded_s) = decoded {
931                assert_eq!(s, decoded_s);
932            } else {
933                panic!("Expected String value");
934            }
935        }
936
937        // Test various Unicode characters
938        let chars = vec!['a', 'é', '日', '🦀'];
939
940        for c in chars {
941            let char_val = Value::Char(c);
942
943            // Test round-trip
944            let encoded = encode_to_vec(&char_val, standard()).unwrap();
945            let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
946
947            if let Value::Char(decoded_c) = decoded {
948                assert_eq!(c, decoded_c);
949            } else {
950                panic!("Expected Char value");
951            }
952        }
953    }
954
955    /// Test ValueDeserializer directly
956    #[test]
957    fn test_value_deserializer() {
958        let original = vec![1, 2, 3];
959        let value = to_value(&original).unwrap();
960
961        // Create a deserializer
962        let deserializer: de::ValueDeserializer<DeserializerError> = ValueDeserializer::new(value);
963
964        // Use it to deserialize
965        let result: Vec<i32> = serde::Deserialize::deserialize(deserializer).unwrap();
966
967        assert_eq!(original, result);
968    }
969
970    /// Test serialization/deserialization with custom types and Option
971    #[test]
972    fn test_option_handling() {
973        // Some values
974        let some_i32 = Some(42);
975        let some_string = Some("test".to_string());
976
977        // None values of different types
978        let none_i32: Option<i32> = None;
979        let none_string: Option<String> = None;
980
981        // Convert to Value
982        let some_i32_value = to_value(some_i32).unwrap();
983        let some_string_value = to_value(&some_string).unwrap();
984        let none_i32_value = to_value(none_i32).unwrap();
985        let none_string_value = to_value(&none_string).unwrap();
986
987        // Check structure
988        assert!(matches!(some_i32_value, Value::Option(Some(_))));
989        assert!(matches!(some_string_value, Value::Option(Some(_))));
990        assert!(matches!(none_i32_value, Value::Option(None)));
991        assert!(matches!(none_string_value, Value::Option(None)));
992
993        // Round-trip
994        let some_i32_rt: Option<i32> = some_i32_value.deserialize_into().unwrap();
995        let some_string_rt: Option<String> = some_string_value.deserialize_into().unwrap();
996        let none_i32_rt: Option<i32> = none_i32_value.deserialize_into().unwrap();
997        let none_string_rt: Option<String> = none_string_value.deserialize_into().unwrap();
998
999        assert_eq!(some_i32, some_i32_rt);
1000        assert_eq!(some_string, some_string_rt);
1001        assert_eq!(none_i32, none_i32_rt);
1002        assert_eq!(none_string, none_string_rt);
1003    }
1004
1005    /// Test deeply nested option values
1006    #[test]
1007    fn test_nested_options() {
1008        // Create deeply nested Option structure
1009        let nested_option: Option<Option<Option<i32>>> = Some(Some(Some(42)));
1010
1011        // Convert to Value
1012        let value = to_value(nested_option).unwrap();
1013
1014        // Verify structure
1015        let mut current = &value;
1016        for _ in 0..3 {
1017            assert!(matches!(current, Value::Option(Some(_))));
1018            if let Value::Option(Some(inner)) = current {
1019                current = inner;
1020            } else {
1021                panic!("Expected Some");
1022            }
1023        }
1024        assert!(matches!(current, Value::I32(42)));
1025
1026        // Round-trip test
1027        let result: Option<Option<Option<i32>>> = value.deserialize_into().unwrap();
1028        assert_eq!(nested_option, result);
1029    }
1030
1031    /// Test conversion behaviors between numeric types
1032    #[test]
1033    fn test_numeric_conversions() {
1034        // Create values of different numeric types
1035        let i8_val = Value::I8(42);
1036        let i16_val = Value::I16(42);
1037        let i32_val = Value::I32(42);
1038        let i64_val = Value::I64(42);
1039        let u8_val = Value::U8(42);
1040        let u16_val = Value::U16(42);
1041        let u32_val = Value::U32(42);
1042        let u64_val = Value::U64(42);
1043        let u64_val_large = Value::U64(u64::MAX);
1044        let f32_val = Value::F32(42.0);
1045        let f64_val = Value::F64(42.0);
1046
1047        // Test valid conversions
1048        // Note: Some of these might depend on implementation details
1049        assert!(i8_val.deserialize_into::<i16>().is_ok());
1050        assert!(i16_val.deserialize_into::<i32>().is_ok());
1051        assert!(i32_val.clone().deserialize_into::<i64>().is_ok());
1052        assert!(u8_val.deserialize_into::<u16>().is_ok());
1053        assert!(u16_val.deserialize_into::<u32>().is_ok());
1054        assert!(u32_val.deserialize_into::<u64>().is_ok());
1055        assert!(u64_val.clone().deserialize_into::<f64>().is_ok());
1056        assert!(i32_val.deserialize_into::<f32>().is_ok());
1057        assert!(f32_val.deserialize_into::<f64>().is_ok());
1058        assert!(i64_val.clone().deserialize_into::<f64>().is_ok());
1059        assert!(u64_val.deserialize_into::<i8>().is_ok());
1060
1061        // Test conversions that shouldn't work
1062        assert!(u64_val_large.deserialize_into::<i8>().is_err());
1063        assert!(f64_val.deserialize_into::<u32>().is_err());
1064        assert!(i64_val.deserialize_into::<bool>().is_err());
1065    }
1066
1067    /// Test Display implementation
1068    #[test]
1069    fn test_display_implementation() {
1070        // Sample different value types and check their string representation
1071        let values = [
1072            (Value::Bool(true), "true"),
1073            (Value::I32(42), "42"),
1074            (Value::String("test".to_string()), "test"),
1075            (Value::Unit, "()"),
1076            (
1077                Value::CuTime(CuTime::from(CuDuration(1_000_000_000))),
1078                "1.000 s",
1079            ),
1080        ];
1081
1082        for (val, expected) in values {
1083            assert_eq!(val.to_string(), expected);
1084        }
1085
1086        // More complex values
1087        let seq = Value::Seq(vec![Value::I32(1), Value::I32(2), Value::I32(3)]);
1088        assert_eq!(seq.to_string(), "[1, 2, 3]");
1089
1090        let mut map = BTreeMap::new();
1091        map.insert(Value::String("key".to_string()), Value::Bool(true));
1092        let map_val = Value::Map(map);
1093        assert_eq!(map_val.to_string(), "{key: true}");
1094    }
1095    #[test]
1096    fn test_numeric_overflow_detection() {
1097        // Test overflow detection
1098        let large_i64 = Value::I64(i64::MAX);
1099        assert!(large_i64.deserialize_into::<i32>().is_err());
1100
1101        // Test underflow detection
1102        let negative = Value::I64(-1);
1103        assert!(negative.deserialize_into::<u64>().is_err());
1104
1105        // Edge case: exactly at boundary
1106        let max_i32 = Value::I64(i32::MAX as i64);
1107        assert!(max_i32.deserialize_into::<i32>().is_ok());
1108
1109        // Edge case: one beyond boundary
1110        let beyond_max_i32 = Value::I64((i32::MAX as i64) + 1);
1111        assert!(beyond_max_i32.deserialize_into::<i32>().is_err());
1112    }
1113
1114    #[test]
1115    fn test_float_precision_handling() {
1116        // Integer -> float -> integer round trip
1117        let original = i64::MAX;
1118        let as_value = Value::I64(original);
1119        let as_f64: f64 = as_value.deserialize_into().unwrap();
1120        let round_trip = Value::F64(as_f64).deserialize_into::<i64>();
1121
1122        // the round_trip should return Error since f64 cannot represent all i64 values
1123        assert!(round_trip.is_err());
1124
1125        // Fractional values to integers
1126        let half = Value::F64(0.5);
1127        let half_as_i32 = half.deserialize_into::<i32>();
1128        assert!(half_as_i32.is_err());
1129    }
1130
1131    #[test]
1132    fn test_float_special_values() {
1133        // NaN to integer
1134        let nan = Value::F64(f64::NAN);
1135        assert!(nan.deserialize_into::<i32>().is_err());
1136
1137        // Infinity to integer
1138        let infinity = Value::F64(f64::INFINITY);
1139        assert!(infinity.deserialize_into::<i64>().is_err());
1140
1141        // Huge values within float range but beyond integer range
1142        let huge = Value::F64(1e20);
1143        assert!(huge.deserialize_into::<i64>().is_err());
1144    }
1145}