1#![doc(html_root_url = "https://docs.rs/serde-value/0.7.0/")]
2
3use cu29_clock::{CuDuration, CuTime};
4use ordered_float::OrderedFloat;
5use serde::Deserialize;
6use std::cmp::Ordering;
7use std::collections::BTreeMap;
8use std::fmt::{Display, Formatter};
9use std::hash::{Hash, Hasher};
10
11mod bdec;
12mod benc;
13mod de;
14mod ser;
15
16pub use de::*;
17pub use ser::*;
18
19#[derive(Clone, Debug)]
20pub enum Value {
21 Bool(bool),
22
23 U8(u8),
24 U16(u16),
25 U32(u32),
26 U64(u64),
27
28 I8(i8),
29 I16(i16),
30 I32(i32),
31 I64(i64),
32
33 F32(f32),
34 F64(f64),
35
36 Char(char),
37 String(String),
38 Unit,
39 Option(Option<Box<Value>>),
40 Newtype(Box<Value>),
41 Seq(Vec<Value>),
42 Map(BTreeMap<Value, Value>),
43 Bytes(Vec<u8>),
44
45 CuTime(CuTime),
46}
47
48impl Display for Value {
49 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
50 match self {
51 Value::Bool(v) => write!(f, "{v}"),
52 Value::U8(v) => write!(f, "{v}"),
53 Value::U16(v) => write!(f, "{v}"),
54 Value::U32(v) => write!(f, "{v}"),
55 Value::U64(v) => write!(f, "{v}"),
56 Value::I8(v) => write!(f, "{v}"),
57 Value::I16(v) => write!(f, "{v}"),
58 Value::I32(v) => write!(f, "{v}"),
59 Value::I64(v) => write!(f, "{v}"),
60 Value::F32(v) => write!(f, "{v}"),
61 Value::F64(v) => write!(f, "{v}"),
62 Value::Char(v) => write!(f, "{v}"),
63 Value::String(v) => write!(f, "{v}"),
64 Value::Unit => write!(f, "()"),
65 Value::Option(v) => match v {
66 Some(v) => write!(f, "Some({v})"),
67 None => write!(f, "None"),
68 },
69 Value::Newtype(v) => write!(f, "{v}"),
70 Value::Seq(v) => {
71 write!(f, "[")?;
72 for (i, v) in v.iter().enumerate() {
73 if i > 0 {
74 write!(f, ", ")?;
75 }
76 write!(f, "{v}")?;
77 }
78 write!(f, "]")
79 }
80 Value::Map(v) => {
81 write!(f, "{{")?;
82 for (i, (k, v)) in v.iter().enumerate() {
83 if i > 0 {
84 write!(f, ", ")?;
85 }
86 write!(f, "{k}: {v}")?;
87 }
88 write!(f, "}}")
89 }
90 Value::Bytes(v) => {
91 write!(f, "[")?;
92 for (i, b) in v.iter().enumerate() {
93 if i > 0 {
94 write!(f, " ")?;
95 }
96 write!(f, "{b:02x}")?;
97 }
98 write!(f, "]")
99 }
100 Value::CuTime(v) => write!(f, "{v}"),
101 }
102 }
103}
104
105impl Hash for Value {
106 fn hash<H>(&self, hasher: &mut H)
107 where
108 H: Hasher,
109 {
110 self.discriminant().hash(hasher);
111 match *self {
112 Value::Bool(v) => v.hash(hasher),
113 Value::U8(v) => v.hash(hasher),
114 Value::U16(v) => v.hash(hasher),
115 Value::U32(v) => v.hash(hasher),
116 Value::U64(v) => v.hash(hasher),
117 Value::I8(v) => v.hash(hasher),
118 Value::I16(v) => v.hash(hasher),
119 Value::I32(v) => v.hash(hasher),
120 Value::I64(v) => v.hash(hasher),
121 Value::F32(v) => OrderedFloat(v).hash(hasher),
122 Value::F64(v) => OrderedFloat(v).hash(hasher),
123 Value::Char(v) => v.hash(hasher),
124 Value::String(ref v) => v.hash(hasher),
125 Value::Unit => 0_u8.hash(hasher),
126 Value::Option(ref v) => v.hash(hasher),
127 Value::Newtype(ref v) => v.hash(hasher),
128 Value::Seq(ref v) => v.hash(hasher),
129 Value::Map(ref v) => v.hash(hasher),
130 Value::Bytes(ref v) => v.hash(hasher),
131 Value::CuTime(v) => {
132 let CuDuration(nanos) = v;
133 nanos.hash(hasher)
134 }
135 }
136 }
137}
138
139impl PartialEq for Value {
140 fn eq(&self, rhs: &Self) -> bool {
141 match (self, rhs) {
142 (&Value::Bool(v0), &Value::Bool(v1)) if v0 == v1 => true,
143 (&Value::U8(v0), &Value::U8(v1)) if v0 == v1 => true,
144 (&Value::U16(v0), &Value::U16(v1)) if v0 == v1 => true,
145 (&Value::U32(v0), &Value::U32(v1)) if v0 == v1 => true,
146 (&Value::U64(v0), &Value::U64(v1)) if v0 == v1 => true,
147 (&Value::I8(v0), &Value::I8(v1)) if v0 == v1 => true,
148 (&Value::I16(v0), &Value::I16(v1)) if v0 == v1 => true,
149 (&Value::I32(v0), &Value::I32(v1)) if v0 == v1 => true,
150 (&Value::I64(v0), &Value::I64(v1)) if v0 == v1 => true,
151 (&Value::F32(v0), &Value::F32(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
152 (&Value::F64(v0), &Value::F64(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
153 (&Value::Char(v0), &Value::Char(v1)) if v0 == v1 => true,
154 (Value::String(v0), Value::String(v1)) if v0 == v1 => true,
155 (&Value::Unit, &Value::Unit) => true,
156 (Value::Option(v0), Value::Option(v1)) if v0 == v1 => true,
157 (Value::Newtype(v0), Value::Newtype(v1)) if v0 == v1 => true,
158 (Value::Seq(v0), Value::Seq(v1)) if v0 == v1 => true,
159 (Value::Map(v0), Value::Map(v1)) if v0 == v1 => true,
160 (Value::Bytes(v0), Value::Bytes(v1)) if v0 == v1 => true,
161 (&Value::CuTime(v0), &Value::CuTime(v1)) if v0 == v1 => true,
162 _ => false,
163 }
164 }
165}
166
167impl Ord for Value {
168 fn cmp(&self, rhs: &Self) -> Ordering {
169 match (self, rhs) {
170 (&Value::Bool(v0), Value::Bool(v1)) => v0.cmp(v1),
171 (&Value::U8(v0), Value::U8(v1)) => v0.cmp(v1),
172 (&Value::U16(v0), Value::U16(v1)) => v0.cmp(v1),
173 (&Value::U32(v0), Value::U32(v1)) => v0.cmp(v1),
174 (&Value::U64(v0), Value::U64(v1)) => v0.cmp(v1),
175 (&Value::I8(v0), Value::I8(v1)) => v0.cmp(v1),
176 (&Value::I16(v0), Value::I16(v1)) => v0.cmp(v1),
177 (&Value::I32(v0), Value::I32(v1)) => v0.cmp(v1),
178 (&Value::I64(v0), Value::I64(v1)) => v0.cmp(v1),
179 (&Value::F32(v0), &Value::F32(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
180 (&Value::F64(v0), &Value::F64(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
181 (&Value::Char(v0), Value::Char(v1)) => v0.cmp(v1),
182 (Value::String(v0), Value::String(v1)) => v0.cmp(v1),
183 (&Value::Unit, &Value::Unit) => Ordering::Equal,
184 (Value::Option(v0), Value::Option(v1)) => v0.cmp(v1),
185 (Value::Newtype(v0), Value::Newtype(v1)) => v0.cmp(v1),
186 (Value::Seq(v0), Value::Seq(v1)) => v0.cmp(v1),
187 (Value::Map(v0), Value::Map(v1)) => v0.cmp(v1),
188 (Value::Bytes(v0), Value::Bytes(v1)) => v0.cmp(v1),
189 (&Value::CuTime(v0), &Value::CuTime(v1)) => v0.cmp(&v1),
190 (v0, v1) => v0.discriminant().cmp(&v1.discriminant()),
191 }
192 }
193}
194
195impl Value {
196 fn discriminant(&self) -> usize {
197 match *self {
198 Value::Bool(..) => 0,
199 Value::U8(..) => 1,
200 Value::U16(..) => 2,
201 Value::U32(..) => 3,
202 Value::U64(..) => 4,
203 Value::I8(..) => 5,
204 Value::I16(..) => 6,
205 Value::I32(..) => 7,
206 Value::I64(..) => 8,
207 Value::F32(..) => 9,
208 Value::F64(..) => 10,
209 Value::Char(..) => 11,
210 Value::String(..) => 12,
211 Value::Unit => 13,
212 Value::Option(..) => 14,
213 Value::Newtype(..) => 15,
214 Value::Seq(..) => 16,
215 Value::Map(..) => 17,
216 Value::Bytes(..) => 18,
217 Value::CuTime(..) => 32,
218 }
219 }
220
221 fn unexpected(&self) -> serde::de::Unexpected<'_> {
222 match *self {
223 Value::Bool(b) => serde::de::Unexpected::Bool(b),
224 Value::U8(n) => serde::de::Unexpected::Unsigned(n as u64),
225 Value::U16(n) => serde::de::Unexpected::Unsigned(n as u64),
226 Value::U32(n) => serde::de::Unexpected::Unsigned(n as u64),
227 Value::U64(n) => serde::de::Unexpected::Unsigned(n),
228 Value::I8(n) => serde::de::Unexpected::Signed(n as i64),
229 Value::I16(n) => serde::de::Unexpected::Signed(n as i64),
230 Value::I32(n) => serde::de::Unexpected::Signed(n as i64),
231 Value::I64(n) => serde::de::Unexpected::Signed(n),
232 Value::F32(n) => serde::de::Unexpected::Float(n as f64),
233 Value::F64(n) => serde::de::Unexpected::Float(n),
234 Value::Char(c) => serde::de::Unexpected::Char(c),
235 Value::String(ref s) => serde::de::Unexpected::Str(s),
236 Value::Unit => serde::de::Unexpected::Unit,
237 Value::Option(_) => serde::de::Unexpected::Option,
238 Value::Newtype(_) => serde::de::Unexpected::NewtypeStruct,
239 Value::Seq(_) => serde::de::Unexpected::Seq,
240 Value::Map(_) => serde::de::Unexpected::Map,
241 Value::Bytes(ref b) => serde::de::Unexpected::Bytes(b),
242 Value::CuTime(n) => {
243 let CuDuration(nanos) = n;
244 serde::de::Unexpected::Unsigned(nanos)
245 }
246 }
247 }
248
249 pub fn deserialize_into<'de, T: Deserialize<'de>>(self) -> Result<T, DeserializerError> {
250 T::deserialize(self)
251 }
252}
253
254impl Eq for Value {}
255impl PartialOrd for Value {
256 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
257 Some(self.cmp(rhs))
258 }
259}
260
261#[cfg(test)]
262mod tests {
263 use super::*;
264 use bincode::{config::standard, decode_from_slice, encode_to_vec};
265 use cu29_clock::{CuDuration, CuTime, RobotClock};
266 use serde_derive::{Deserialize, Serialize};
267 use std::collections::{hash_map::DefaultHasher, BTreeMap};
268 use std::hash::{Hash, Hasher};
269 use std::time::Duration;
270
271 #[test]
272 fn de_smoke_test() {
273 let value = Value::Option(Some(Box::new(Value::Seq(vec![
275 Value::U16(8),
276 Value::Char('a'),
277 Value::F32(1.0),
278 Value::String("hello".into()),
279 Value::Map(
280 vec![
281 (Value::Bool(false), Value::Unit),
282 (
283 Value::Bool(true),
284 Value::Newtype(Box::new(Value::Bytes(b"hi".as_ref().into()))),
285 ),
286 ]
287 .into_iter()
288 .collect(),
289 ),
290 ]))));
291
292 let value_de = Value::deserialize(value.clone()).unwrap();
294 assert_eq!(value_de, value);
295 }
296
297 #[test]
298 fn ser_smoke_test() {
299 #[derive(Serialize)]
300 struct Foo {
301 a: u32,
302 b: String,
303 c: Vec<bool>,
304 }
305
306 let foo = Foo {
307 a: 15,
308 b: "hello".into(),
309 c: vec![true, false],
310 };
311
312 let expected = Value::Map(
313 vec![
314 (Value::String("a".into()), Value::U32(15)),
315 (Value::String("b".into()), Value::String("hello".into())),
316 (
317 Value::String("c".into()),
318 Value::Seq(vec![Value::Bool(true), Value::Bool(false)]),
319 ),
320 ]
321 .into_iter()
322 .collect(),
323 );
324
325 let value = to_value(&foo).unwrap();
326 assert_eq!(expected, value);
327 }
328
329 #[test]
330 fn deserialize_into_enum() {
331 #[derive(Deserialize, Debug, PartialEq, Eq)]
332 enum Foo {
333 Bar,
334 Baz(u8),
335 }
336
337 let value = Value::String("Bar".into());
338 assert_eq!(Foo::deserialize(value).unwrap(), Foo::Bar);
339
340 let value = Value::Map(
341 vec![(Value::String("Baz".into()), Value::U8(1))]
342 .into_iter()
343 .collect(),
344 );
345 assert_eq!(Foo::deserialize(value).unwrap(), Foo::Baz(1));
346 }
347
348 #[test]
349 fn serialize_from_enum() {
350 #[derive(Serialize)]
351 enum Foo {
352 Bar,
353 Baz(u8),
354 Qux { quux: u8 },
355 Corge(u8, u8),
356 }
357
358 let bar = Foo::Bar;
359 assert_eq!(to_value(&bar).unwrap(), Value::String("Bar".into()));
360
361 let baz = Foo::Baz(1);
362 assert_eq!(
363 to_value(&baz).unwrap(),
364 Value::Map(
365 vec![(Value::String("Baz".into()), Value::U8(1))]
366 .into_iter()
367 .collect(),
368 )
369 );
370
371 let qux = Foo::Qux { quux: 2 };
372 assert_eq!(
373 to_value(&qux).unwrap(),
374 Value::Map(
375 vec![(
376 Value::String("Qux".into()),
377 Value::Map(
378 vec![(Value::String("quux".into()), Value::U8(2))]
379 .into_iter()
380 .collect()
381 )
382 )]
383 .into_iter()
384 .collect()
385 )
386 );
387
388 let corge = Foo::Corge(3, 4);
389 assert_eq!(
390 to_value(&corge).unwrap(),
391 Value::Map(
392 vec![(
393 Value::String("Corge".into()),
394 Value::Seq(vec![Value::U8(3), Value::U8(4)])
395 )]
396 .into_iter()
397 .collect()
398 )
399 );
400 }
401
402 #[test]
403 fn deserialize_inside_deserialize_impl() {
404 #[derive(Debug, PartialEq, Eq)]
405 enum Event {
406 Added(u32),
407 Error(u8),
408 }
409
410 impl<'de> serde::Deserialize<'de> for Event {
411 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
412 where
413 D: serde::Deserializer<'de>,
414 {
415 #[derive(Deserialize)]
416 struct RawEvent {
417 kind: String,
418 object: Value,
419 }
420
421 let raw_event = RawEvent::deserialize(deserializer)?;
422
423 let object_deserializer = ValueDeserializer::new(raw_event.object);
426
427 Ok(match &*raw_event.kind {
428 "ADDED" => Event::Added(<_>::deserialize(object_deserializer)?),
429 "ERROR" => Event::Error(<_>::deserialize(object_deserializer)?),
430 kind => {
431 return Err(serde::de::Error::unknown_variant(kind, &["ADDED", "ERROR"]))
432 }
433 })
434 }
435 }
436
437 let input = Value::Map(
438 vec![
439 (
440 Value::String("kind".to_owned()),
441 Value::String("ADDED".to_owned()),
442 ),
443 (Value::String("object".to_owned()), Value::U32(5)),
444 ]
445 .into_iter()
446 .collect(),
447 );
448 let event = Event::deserialize(input).expect("could not deserialize ADDED event");
449 assert_eq!(event, Event::Added(5));
450
451 let input = Value::Map(
452 vec![
453 (
454 Value::String("kind".to_owned()),
455 Value::String("ERROR".to_owned()),
456 ),
457 (Value::String("object".to_owned()), Value::U8(5)),
458 ]
459 .into_iter()
460 .collect(),
461 );
462 let event = Event::deserialize(input).expect("could not deserialize ERROR event");
463 assert_eq!(event, Event::Error(5));
464
465 let input = Value::Map(
466 vec![
467 (
468 Value::String("kind".to_owned()),
469 Value::String("ADDED".to_owned()),
470 ),
471 (Value::String("object".to_owned()), Value::Unit),
472 ]
473 .into_iter()
474 .collect(),
475 );
476 let _ =
477 Event::deserialize(input).expect_err("expected deserializing bad ADDED event to fail");
478 }
479
480 #[test]
481 fn deserialize_newtype() {
482 #[derive(Debug, Deserialize, PartialEq)]
483 struct Foo(i32);
484
485 let input = Value::I32(5);
486 let foo = Foo::deserialize(input).unwrap();
487 assert_eq!(foo, Foo(5));
488 }
489
490 #[test]
491 fn deserialize_newtype2() {
492 #[derive(Debug, Deserialize, PartialEq)]
493 struct Foo(i32);
494
495 #[derive(Debug, Deserialize, PartialEq)]
496 struct Bar {
497 foo: Foo,
498 }
499
500 let input = Value::Map(
501 vec![(Value::String("foo".to_owned()), Value::I32(5))]
502 .into_iter()
503 .collect(),
504 );
505 let bar = Bar::deserialize(input).unwrap();
506 assert_eq!(bar, Bar { foo: Foo(5) });
507 }
508
509 #[test]
510 fn clock_ser_deser() {
511 let (clock, mock) = RobotClock::mock();
512 mock.increment(Duration::from_nanos(42));
513 let c = clock.now();
514
515 let input = Value::CuTime(c);
516 let foo = CuTime::deserialize(input).unwrap();
517 assert_eq!(foo, CuTime::from(Duration::from_nanos(42)));
518 }
519 #[test]
520 fn value_encode_decode() {
521 fn check_value(value: Value) {
522 let v = bincode::encode_to_vec(&value, standard()).expect("encode failed");
523 let (v2, s) = bincode::decode_from_slice::<Value, _>(v.as_slice(), standard())
524 .expect("decode failed");
525 assert_eq!(s, v.len());
526 assert_eq!(&v2, &value);
527 }
528
529 check_value(Value::Bool(true));
530 check_value(Value::U8(42));
531 check_value(Value::U16(42));
532 check_value(Value::U32(42));
533 check_value(Value::U64(42));
534 check_value(Value::I8(42));
535 check_value(Value::I16(42));
536 check_value(Value::I32(42));
537 check_value(Value::I64(42));
538 check_value(Value::F32(42.42));
539 check_value(Value::F64(42.42));
540 check_value(Value::Char('4'));
541 check_value(Value::String("42".into()));
542 check_value(Value::Unit);
543 check_value(Value::Option(Some(Box::new(Value::U32(42)))));
544 check_value(Value::Newtype(Box::new(Value::U32(42))));
545 check_value(Value::Seq(vec![Value::Bool(true), Value::U32(42)]));
546 check_value(Value::Map(BTreeMap::from([
547 (Value::Bool(true), Value::U32(42)),
548 (Value::String("42".into()), Value::I32(42)),
549 ])));
550 check_value(Value::Bytes(vec![0x4, 0x2]));
551 check_value(Value::CuTime(CuTime::from(Duration::from_nanos(42))));
552 }
553
554 #[test]
555 fn test_cutime_tovalue() {
556 let c = CuTime::from(Duration::from_nanos(42));
557 let v = to_value(c).expect("to_value failed");
558 assert_eq!(v, Value::CuTime(c));
559 }
560 #[test]
562 fn test_value_creation_and_types() {
563 let bool_val = Value::Bool(true);
565 let i32_val = Value::I32(42);
566 let str_val = Value::String("test".to_string());
567 let unit_val = Value::Unit;
568 let option_val = Value::Option(Some(Box::new(Value::U8(5))));
569
570 assert!(matches!(bool_val, Value::Bool(true)));
572 assert!(matches!(i32_val, Value::I32(42)));
573 assert!(matches!(str_val, Value::String(ref s) if s == "test"));
574 assert!(matches!(unit_val, Value::Unit));
575 assert!(matches!(option_val, Value::Option(Some(_))));
576
577 assert_eq!(bool_val.discriminant(), 0);
579 assert_eq!(i32_val.discriminant(), 7);
580 assert_eq!(str_val.discriminant(), 12);
581 }
582
583 #[test]
585 fn test_numeric_boundaries_and_special_values() {
586 let min_i8 = Value::I8(i8::MIN);
588 let max_i8 = Value::I8(i8::MAX);
589 let min_i64 = Value::I64(i64::MIN);
590 let max_u64 = Value::U64(u64::MAX);
591
592 let nan = Value::F64(f64::NAN);
594 let pos_inf = Value::F64(f64::INFINITY);
595 let neg_inf = Value::F64(f64::NEG_INFINITY);
596 let zero = Value::F64(0.0);
597 let neg_zero = Value::F64(-0.0);
598
599 for val in [
601 min_i8,
602 max_i8,
603 min_i64,
604 max_u64,
605 nan.clone(),
606 pos_inf.clone(),
607 neg_inf.clone(),
608 zero.clone(),
609 neg_zero.clone(),
610 ] {
611 let encoded = encode_to_vec(&val, standard()).unwrap();
612 let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
613
614 if matches!(val, Value::F64(f) if f.is_nan()) {
616 assert!(matches!(decoded, Value::F64(f) if f.is_nan()));
617 } else {
618 assert_eq!(val, decoded);
619 }
620 }
621
622 assert!(pos_inf > zero);
624 assert!(neg_inf < zero);
625
626 let nan2 = Value::F64(f64::NAN);
628 assert_eq!(nan, nan2); assert_eq!(zero, neg_zero);
632 }
633
634 #[test]
636 fn test_container_types() {
637 let empty_seq = Value::Seq(vec![]);
639 let empty_map = Value::Map(BTreeMap::new());
640
641 let simple_seq = Value::Seq(vec![Value::I32(1), Value::I32(2), Value::I32(3)]);
643 let mut simple_map = BTreeMap::new();
644 simple_map.insert(Value::String("key".to_string()), Value::Bool(true));
645 let simple_map_val = Value::Map(simple_map);
646
647 let mut nested_map = BTreeMap::new();
649 nested_map.insert(
650 Value::String("outer".to_string()),
651 Value::Seq(vec![
652 Value::Option(Some(Box::new(Value::Map({
653 let mut m = BTreeMap::new();
654 m.insert(Value::I32(1), Value::String("nested".to_string()));
655 m
656 })))),
657 Value::Bool(false),
658 ]),
659 );
660 let nested_val = Value::Map(nested_map);
661
662 for val in [empty_seq, empty_map, simple_seq, simple_map_val, nested_val] {
664 let encoded = encode_to_vec(&val, standard()).unwrap();
665 let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
666 assert_eq!(val, decoded);
667 }
668 }
669
670 #[test]
672 fn test_large_values() {
673 let large_seq = Value::Seq((0..10000).map(Value::I32).collect());
675
676 let large_string = Value::String("x".repeat(100000));
678
679 let large_bytes = Value::Bytes((0..10000).map(|i| (i % 256) as u8).collect());
681
682 let mut large_map = BTreeMap::new();
684 for i in 0..1000 {
685 large_map.insert(
686 Value::I32(i),
687 Value::Seq((0..10).map(|j| Value::I32(i * j)).collect()),
688 );
689 }
690 let large_nested = Value::Map(large_map);
691
692 for val in [large_seq, large_string, large_bytes, large_nested] {
694 let encoded = encode_to_vec(&val, standard()).unwrap();
695 let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
696 assert_eq!(val, decoded);
697 }
698 }
699
700 #[test]
702 fn test_value_comparison() {
703 assert!(Value::I32(1) < Value::I32(2));
705 assert!(Value::String("a".to_string()) < Value::String("b".to_string()));
706 assert!(Value::Bool(false) < Value::Bool(true));
707
708 assert!(Value::Bool(true) < Value::I32(0)); assert!(Value::I32(100) < Value::String("a".to_string())); assert!(
714 Value::Seq(vec![Value::I32(1), Value::I32(2)])
715 < Value::Seq(vec![Value::I32(1), Value::I32(3)])
716 );
717
718 let mut map1 = BTreeMap::new();
719 map1.insert(Value::String("key".to_string()), Value::I32(1));
720
721 let mut map2 = BTreeMap::new();
722 map2.insert(Value::String("key".to_string()), Value::I32(2));
723
724 assert!(Value::Map(map1) < Value::Map(map2));
725
726 let nan1 = Value::F64(f64::NAN);
728 let nan2 = Value::F64(f64::NAN);
729 assert_eq!(nan1, nan2); }
731
732 #[test]
734 fn test_value_hashing() {
735 let values = [
736 Value::Bool(true),
737 Value::I32(42),
738 Value::String("hash me".to_string()),
739 Value::F64(3.1),
740 Value::Char('🦀'),
741 Value::Option(Some(Box::new(Value::U8(5)))),
742 Value::Unit,
743 ];
744
745 for val in values {
746 let mut hasher1 = DefaultHasher::new();
748 let mut hasher2 = DefaultHasher::new();
749 val.hash(&mut hasher1);
750 val.hash(&mut hasher2);
751 assert_eq!(hasher1.finish(), hasher2.finish());
752
753 let val_clone = val.clone();
755 let mut hasher3 = DefaultHasher::new();
756 val_clone.hash(&mut hasher3);
757 assert_eq!(hasher1.finish(), hasher3.finish());
758 }
759
760 let nan1 = Value::F64(f64::NAN);
762 let nan2 = Value::F64(f64::NAN);
763
764 let mut hasher1 = DefaultHasher::new();
765 let mut hasher2 = DefaultHasher::new();
766 nan1.hash(&mut hasher1);
767 nan2.hash(&mut hasher2);
768 assert_eq!(hasher1.finish(), hasher2.finish());
769 }
770
771 #[test]
773 fn test_struct_serde() {
774 #[derive(Serialize, Deserialize, Debug, PartialEq)]
775 struct Person {
776 name: String,
777 age: u32,
778 addresses: Vec<Address>,
779 }
780
781 #[derive(Serialize, Deserialize, Debug, PartialEq)]
782 struct Address {
783 street: String,
784 city: String,
785 zip: u32,
786 }
787
788 let person = Person {
789 name: "Alice".to_string(),
790 age: 30,
791 addresses: vec![
792 Address {
793 street: "123 Main St".to_string(),
794 city: "Anytown".to_string(),
795 zip: 12345,
796 },
797 Address {
798 street: "456 Oak Ave".to_string(),
799 city: "Somewhere".to_string(),
800 zip: 67890,
801 },
802 ],
803 };
804
805 let value = to_value(&person).unwrap();
807
808 assert!(matches!(value, Value::Map(_)));
810
811 let person2 = value.deserialize_into::<Person>().unwrap();
813 assert_eq!(person, person2);
814 }
815
816 #[test]
818 fn test_enum_serde() {
819 #[derive(Serialize, Deserialize, Debug, PartialEq)]
820 enum MyEnum {
821 Unit,
822 NewType(i32),
823 Tuple(String, bool),
824 Struct { x: f64, y: f64 },
825 }
826
827 let variants = vec![
829 MyEnum::Unit,
830 MyEnum::NewType(42),
831 MyEnum::Tuple("hello".to_string(), true),
832 MyEnum::Struct { x: 1.0, y: 2.0 },
833 ];
834
835 for variant in variants {
836 let value = to_value(&variant).unwrap();
837 let roundtrip = value.deserialize_into::<MyEnum>().unwrap();
838 assert_eq!(variant, roundtrip);
839 }
840 }
841
842 #[test]
844 fn test_cutime_handling() {
845 let times = vec![
847 CuTime::from(CuDuration(0)),
848 CuTime::from(CuDuration(1)),
849 CuTime::from(CuDuration(u64::MAX / 2)),
850 ];
852
853 for time in times {
854 let time_value = Value::CuTime(time);
856
857 let encoded = encode_to_vec(&time_value, standard()).unwrap();
859 let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
860 assert_eq!(time_value, decoded);
861
862 let via_to_value = to_value(time).unwrap();
864 assert_eq!(via_to_value, time_value);
865
866 let time_roundtrip = via_to_value.deserialize_into::<CuTime>().unwrap();
868 assert_eq!(time, time_roundtrip);
869 }
870 }
871
872 #[test]
874 fn test_error_handling() {
875 let bool_val = Value::Bool(true);
877 let result = bool_val.clone().deserialize_into::<i32>();
878 assert!(result.is_err());
879
880 let empty_map = Value::Map(BTreeMap::new());
882
883 #[derive(Deserialize)]
884 struct RequiredFields {
885 _required: String,
886 }
887
888 let result = empty_map.deserialize_into::<RequiredFields>();
889 assert!(result.is_err());
890
891 let invalid_variant = Value::String("NonExistentVariant".to_string());
893
894 #[derive(Deserialize)]
895 enum TestEnum {
896 A,
897 B,
898 C,
899 }
900
901 let result = invalid_variant.deserialize_into::<TestEnum>();
902 assert!(result.is_err());
903
904 match bool_val.deserialize_into::<String>() {
906 Err(DeserializerError::InvalidType(..)) => (), other => panic!("Expected InvalidType error, got: {other:?}"),
908 }
909 }
910
911 #[test]
913 fn test_unicode_handling() {
914 let strings = vec![
915 "".to_string(), "ASCII only".to_string(), "Café 🍰".to_string(), "日本語".to_string(), "👨👩👧👦 Family".to_string(), "ᛁᚲ ᚲᚨᚾ ᚱᚢᚾᛖᛋ".to_string(), ];
922
923 for s in strings {
924 let string_val = Value::String(s.clone());
925
926 let encoded = encode_to_vec(&string_val, standard()).unwrap();
928 let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
929
930 if let Value::String(decoded_s) = decoded {
931 assert_eq!(s, decoded_s);
932 } else {
933 panic!("Expected String value");
934 }
935 }
936
937 let chars = vec!['a', 'é', '日', '🦀'];
939
940 for c in chars {
941 let char_val = Value::Char(c);
942
943 let encoded = encode_to_vec(&char_val, standard()).unwrap();
945 let (decoded, _): (Value, _) = decode_from_slice(&encoded, standard()).unwrap();
946
947 if let Value::Char(decoded_c) = decoded {
948 assert_eq!(c, decoded_c);
949 } else {
950 panic!("Expected Char value");
951 }
952 }
953 }
954
955 #[test]
957 fn test_value_deserializer() {
958 let original = vec![1, 2, 3];
959 let value = to_value(&original).unwrap();
960
961 let deserializer: de::ValueDeserializer<DeserializerError> = ValueDeserializer::new(value);
963
964 let result: Vec<i32> = serde::Deserialize::deserialize(deserializer).unwrap();
966
967 assert_eq!(original, result);
968 }
969
970 #[test]
972 fn test_option_handling() {
973 let some_i32 = Some(42);
975 let some_string = Some("test".to_string());
976
977 let none_i32: Option<i32> = None;
979 let none_string: Option<String> = None;
980
981 let some_i32_value = to_value(some_i32).unwrap();
983 let some_string_value = to_value(&some_string).unwrap();
984 let none_i32_value = to_value(none_i32).unwrap();
985 let none_string_value = to_value(&none_string).unwrap();
986
987 assert!(matches!(some_i32_value, Value::Option(Some(_))));
989 assert!(matches!(some_string_value, Value::Option(Some(_))));
990 assert!(matches!(none_i32_value, Value::Option(None)));
991 assert!(matches!(none_string_value, Value::Option(None)));
992
993 let some_i32_rt: Option<i32> = some_i32_value.deserialize_into().unwrap();
995 let some_string_rt: Option<String> = some_string_value.deserialize_into().unwrap();
996 let none_i32_rt: Option<i32> = none_i32_value.deserialize_into().unwrap();
997 let none_string_rt: Option<String> = none_string_value.deserialize_into().unwrap();
998
999 assert_eq!(some_i32, some_i32_rt);
1000 assert_eq!(some_string, some_string_rt);
1001 assert_eq!(none_i32, none_i32_rt);
1002 assert_eq!(none_string, none_string_rt);
1003 }
1004
1005 #[test]
1007 fn test_nested_options() {
1008 let nested_option: Option<Option<Option<i32>>> = Some(Some(Some(42)));
1010
1011 let value = to_value(nested_option).unwrap();
1013
1014 let mut current = &value;
1016 for _ in 0..3 {
1017 assert!(matches!(current, Value::Option(Some(_))));
1018 if let Value::Option(Some(inner)) = current {
1019 current = inner;
1020 } else {
1021 panic!("Expected Some");
1022 }
1023 }
1024 assert!(matches!(current, Value::I32(42)));
1025
1026 let result: Option<Option<Option<i32>>> = value.deserialize_into().unwrap();
1028 assert_eq!(nested_option, result);
1029 }
1030
1031 #[test]
1033 fn test_numeric_conversions() {
1034 let i8_val = Value::I8(42);
1036 let i16_val = Value::I16(42);
1037 let i32_val = Value::I32(42);
1038 let i64_val = Value::I64(42);
1039 let u8_val = Value::U8(42);
1040 let u16_val = Value::U16(42);
1041 let u32_val = Value::U32(42);
1042 let u64_val = Value::U64(42);
1043 let u64_val_large = Value::U64(u64::MAX);
1044 let f32_val = Value::F32(42.0);
1045 let f64_val = Value::F64(42.0);
1046
1047 assert!(i8_val.deserialize_into::<i16>().is_ok());
1050 assert!(i16_val.deserialize_into::<i32>().is_ok());
1051 assert!(i32_val.clone().deserialize_into::<i64>().is_ok());
1052 assert!(u8_val.deserialize_into::<u16>().is_ok());
1053 assert!(u16_val.deserialize_into::<u32>().is_ok());
1054 assert!(u32_val.deserialize_into::<u64>().is_ok());
1055 assert!(u64_val.clone().deserialize_into::<f64>().is_ok());
1056 assert!(i32_val.deserialize_into::<f32>().is_ok());
1057 assert!(f32_val.deserialize_into::<f64>().is_ok());
1058 assert!(i64_val.clone().deserialize_into::<f64>().is_ok());
1059 assert!(u64_val.deserialize_into::<i8>().is_ok());
1060
1061 assert!(u64_val_large.deserialize_into::<i8>().is_err());
1063 assert!(f64_val.deserialize_into::<u32>().is_err());
1064 assert!(i64_val.deserialize_into::<bool>().is_err());
1065 }
1066
1067 #[test]
1069 fn test_display_implementation() {
1070 let values = [
1072 (Value::Bool(true), "true"),
1073 (Value::I32(42), "42"),
1074 (Value::String("test".to_string()), "test"),
1075 (Value::Unit, "()"),
1076 (
1077 Value::CuTime(CuTime::from(CuDuration(1_000_000_000))),
1078 "1.000 s",
1079 ),
1080 ];
1081
1082 for (val, expected) in values {
1083 assert_eq!(val.to_string(), expected);
1084 }
1085
1086 let seq = Value::Seq(vec![Value::I32(1), Value::I32(2), Value::I32(3)]);
1088 assert_eq!(seq.to_string(), "[1, 2, 3]");
1089
1090 let mut map = BTreeMap::new();
1091 map.insert(Value::String("key".to_string()), Value::Bool(true));
1092 let map_val = Value::Map(map);
1093 assert_eq!(map_val.to_string(), "{key: true}");
1094 }
1095 #[test]
1096 fn test_numeric_overflow_detection() {
1097 let large_i64 = Value::I64(i64::MAX);
1099 assert!(large_i64.deserialize_into::<i32>().is_err());
1100
1101 let negative = Value::I64(-1);
1103 assert!(negative.deserialize_into::<u64>().is_err());
1104
1105 let max_i32 = Value::I64(i32::MAX as i64);
1107 assert!(max_i32.deserialize_into::<i32>().is_ok());
1108
1109 let beyond_max_i32 = Value::I64((i32::MAX as i64) + 1);
1111 assert!(beyond_max_i32.deserialize_into::<i32>().is_err());
1112 }
1113
1114 #[test]
1115 fn test_float_precision_handling() {
1116 let original = i64::MAX;
1118 let as_value = Value::I64(original);
1119 let as_f64: f64 = as_value.deserialize_into().unwrap();
1120 let round_trip = Value::F64(as_f64).deserialize_into::<i64>();
1121
1122 assert!(round_trip.is_err());
1124
1125 let half = Value::F64(0.5);
1127 let half_as_i32 = half.deserialize_into::<i32>();
1128 assert!(half_as_i32.is_err());
1129 }
1130
1131 #[test]
1132 fn test_float_special_values() {
1133 let nan = Value::F64(f64::NAN);
1135 assert!(nan.deserialize_into::<i32>().is_err());
1136
1137 let infinity = Value::F64(f64::INFINITY);
1139 assert!(infinity.deserialize_into::<i64>().is_err());
1140
1141 let huge = Value::F64(1e20);
1143 assert!(huge.deserialize_into::<i64>().is_err());
1144 }
1145}