Skip to main content

cu29_value/
lib.rs

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