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