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, "{:02x}", b)?;
97 }
98 write!(f, "]")
99 }
100 Value::CuTime(v) => write!(f, "{}", v),
101 }
102 }
103}
104
105impl Hash for Value {
106 fn hash<H>(&self, hasher: &mut H)
107 where
108 H: Hasher,
109 {
110 self.discriminant().hash(hasher);
111 match *self {
112 Value::Bool(v) => v.hash(hasher),
113 Value::U8(v) => v.hash(hasher),
114 Value::U16(v) => v.hash(hasher),
115 Value::U32(v) => v.hash(hasher),
116 Value::U64(v) => v.hash(hasher),
117 Value::I8(v) => v.hash(hasher),
118 Value::I16(v) => v.hash(hasher),
119 Value::I32(v) => v.hash(hasher),
120 Value::I64(v) => v.hash(hasher),
121 Value::F32(v) => OrderedFloat(v).hash(hasher),
122 Value::F64(v) => OrderedFloat(v).hash(hasher),
123 Value::Char(v) => v.hash(hasher),
124 Value::String(ref v) => v.hash(hasher),
125 Value::Unit => 0_u8.hash(hasher),
126 Value::Option(ref v) => v.hash(hasher),
127 Value::Newtype(ref v) => v.hash(hasher),
128 Value::Seq(ref v) => v.hash(hasher),
129 Value::Map(ref v) => v.hash(hasher),
130 Value::Bytes(ref v) => v.hash(hasher),
131 Value::CuTime(v) => {
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;
265 use cu29_clock::RobotClock;
266 use serde_derive::{Deserialize, Serialize};
267 use std::time::Duration;
268
269 #[test]
270 fn de_smoke_test() {
271 let value = Value::Option(Some(Box::new(Value::Seq(vec![
273 Value::U16(8),
274 Value::Char('a'),
275 Value::F32(1.0),
276 Value::String("hello".into()),
277 Value::Map(
278 vec![
279 (Value::Bool(false), Value::Unit),
280 (
281 Value::Bool(true),
282 Value::Newtype(Box::new(Value::Bytes(b"hi".as_ref().into()))),
283 ),
284 ]
285 .into_iter()
286 .collect(),
287 ),
288 ]))));
289
290 let value_de = Value::deserialize(value.clone()).unwrap();
292 assert_eq!(value_de, value);
293 }
294
295 #[test]
296 fn ser_smoke_test() {
297 #[derive(Serialize)]
298 struct Foo {
299 a: u32,
300 b: String,
301 c: Vec<bool>,
302 }
303
304 let foo = Foo {
305 a: 15,
306 b: "hello".into(),
307 c: vec![true, false],
308 };
309
310 let expected = Value::Map(
311 vec![
312 (Value::String("a".into()), Value::U32(15)),
313 (Value::String("b".into()), Value::String("hello".into())),
314 (
315 Value::String("c".into()),
316 Value::Seq(vec![Value::Bool(true), Value::Bool(false)]),
317 ),
318 ]
319 .into_iter()
320 .collect(),
321 );
322
323 let value = to_value(&foo).unwrap();
324 assert_eq!(expected, value);
325 }
326
327 #[test]
328 fn deserialize_into_enum() {
329 #[derive(Deserialize, Debug, PartialEq, Eq)]
330 enum Foo {
331 Bar,
332 Baz(u8),
333 }
334
335 let value = Value::String("Bar".into());
336 assert_eq!(Foo::deserialize(value).unwrap(), Foo::Bar);
337
338 let value = Value::Map(
339 vec![(Value::String("Baz".into()), Value::U8(1))]
340 .into_iter()
341 .collect(),
342 );
343 assert_eq!(Foo::deserialize(value).unwrap(), Foo::Baz(1));
344 }
345
346 #[test]
347 fn serialize_from_enum() {
348 #[derive(Serialize)]
349 enum Foo {
350 Bar,
351 Baz(u8),
352 Qux { quux: u8 },
353 Corge(u8, u8),
354 }
355
356 let bar = Foo::Bar;
357 assert_eq!(to_value(&bar).unwrap(), Value::String("Bar".into()));
358
359 let baz = Foo::Baz(1);
360 assert_eq!(
361 to_value(&baz).unwrap(),
362 Value::Map(
363 vec![(Value::String("Baz".into()), Value::U8(1))]
364 .into_iter()
365 .collect(),
366 )
367 );
368
369 let qux = Foo::Qux { quux: 2 };
370 assert_eq!(
371 to_value(&qux).unwrap(),
372 Value::Map(
373 vec![(
374 Value::String("Qux".into()),
375 Value::Map(
376 vec![(Value::String("quux".into()), Value::U8(2))]
377 .into_iter()
378 .collect()
379 )
380 )]
381 .into_iter()
382 .collect()
383 )
384 );
385
386 let corge = Foo::Corge(3, 4);
387 assert_eq!(
388 to_value(&corge).unwrap(),
389 Value::Map(
390 vec![(
391 Value::String("Corge".into()),
392 Value::Seq(vec![Value::U8(3), Value::U8(4)])
393 )]
394 .into_iter()
395 .collect()
396 )
397 );
398 }
399
400 #[test]
401 fn deserialize_inside_deserialize_impl() {
402 #[derive(Debug, PartialEq, Eq)]
403 enum Event {
404 Added(u32),
405 Error(u8),
406 }
407
408 impl<'de> serde::Deserialize<'de> for Event {
409 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
410 where
411 D: serde::Deserializer<'de>,
412 {
413 #[derive(Deserialize)]
414 struct RawEvent {
415 kind: String,
416 object: Value,
417 }
418
419 let raw_event = RawEvent::deserialize(deserializer)?;
420
421 let object_deserializer = ValueDeserializer::new(raw_event.object);
424
425 Ok(match &*raw_event.kind {
426 "ADDED" => Event::Added(<_>::deserialize(object_deserializer)?),
427 "ERROR" => Event::Error(<_>::deserialize(object_deserializer)?),
428 kind => {
429 return Err(serde::de::Error::unknown_variant(kind, &["ADDED", "ERROR"]))
430 }
431 })
432 }
433 }
434
435 let input = Value::Map(
436 vec![
437 (
438 Value::String("kind".to_owned()),
439 Value::String("ADDED".to_owned()),
440 ),
441 (Value::String("object".to_owned()), Value::U32(5)),
442 ]
443 .into_iter()
444 .collect(),
445 );
446 let event = Event::deserialize(input).expect("could not deserialize ADDED event");
447 assert_eq!(event, Event::Added(5));
448
449 let input = Value::Map(
450 vec![
451 (
452 Value::String("kind".to_owned()),
453 Value::String("ERROR".to_owned()),
454 ),
455 (Value::String("object".to_owned()), Value::U8(5)),
456 ]
457 .into_iter()
458 .collect(),
459 );
460 let event = Event::deserialize(input).expect("could not deserialize ERROR event");
461 assert_eq!(event, Event::Error(5));
462
463 let input = Value::Map(
464 vec![
465 (
466 Value::String("kind".to_owned()),
467 Value::String("ADDED".to_owned()),
468 ),
469 (Value::String("object".to_owned()), Value::Unit),
470 ]
471 .into_iter()
472 .collect(),
473 );
474 let _ =
475 Event::deserialize(input).expect_err("expected deserializing bad ADDED event to fail");
476 }
477
478 #[test]
479 fn deserialize_newtype() {
480 #[derive(Debug, Deserialize, PartialEq)]
481 struct Foo(i32);
482
483 let input = Value::I32(5);
484 let foo = Foo::deserialize(input).unwrap();
485 assert_eq!(foo, Foo(5));
486 }
487
488 #[test]
489 fn deserialize_newtype2() {
490 #[derive(Debug, Deserialize, PartialEq)]
491 struct Foo(i32);
492
493 #[derive(Debug, Deserialize, PartialEq)]
494 struct Bar {
495 foo: Foo,
496 }
497
498 let input = Value::Map(
499 vec![(Value::String("foo".to_owned()), Value::I32(5))]
500 .into_iter()
501 .collect(),
502 );
503 let bar = Bar::deserialize(input).unwrap();
504 assert_eq!(bar, Bar { foo: Foo(5) });
505 }
506
507 #[test]
508 fn clock_ser_deser() {
509 let (clock, mock) = RobotClock::mock();
510 mock.increment(Duration::from_nanos(42));
511 let c = clock.now();
512
513 let input = Value::CuTime(c);
514 let foo = CuTime::deserialize(input).unwrap();
515 assert_eq!(foo, CuTime::from(Duration::from_nanos(42)));
516 }
517 #[test]
518 fn value_encode_decode() {
519 fn check_value(value: Value) {
520 let v = bincode::encode_to_vec(&value, standard()).expect("encode failed");
521 let (v2, s) = bincode::decode_from_slice::<Value, _>(v.as_slice(), standard())
522 .expect("decode failed");
523 assert_eq!(s, v.len());
524 assert_eq!(&v2, &value);
525 }
526
527 check_value(Value::Bool(true));
528 check_value(Value::U8(42));
529 check_value(Value::U16(42));
530 check_value(Value::U32(42));
531 check_value(Value::U64(42));
532 check_value(Value::I8(42));
533 check_value(Value::I16(42));
534 check_value(Value::I32(42));
535 check_value(Value::I64(42));
536 check_value(Value::F32(42.42));
537 check_value(Value::F64(42.42));
538 check_value(Value::Char('4'));
539 check_value(Value::String("42".into()));
540 check_value(Value::Unit);
541 check_value(Value::Option(Some(Box::new(Value::U32(42)))));
542 check_value(Value::Newtype(Box::new(Value::U32(42))));
543 check_value(Value::Seq(vec![Value::Bool(true), Value::U32(42)]));
544 check_value(Value::Map(BTreeMap::from([
545 (Value::Bool(true), Value::U32(42)),
546 (Value::String("42".into()), Value::I32(42)),
547 ])));
548 check_value(Value::Bytes(vec![0x4, 0x2]));
549 check_value(Value::CuTime(CuTime::from(Duration::from_nanos(42))));
550 }
551
552 #[test]
553 fn test_cutime_tovalue() {
554 let c = CuTime::from(Duration::from_nanos(42));
555 let v = to_value(c).expect("to_value failed");
556 assert_eq!(v, Value::CuTime(c));
557 }
558}