1#![doc(html_root_url = "https://docs.rs/serde-value/0.7.0/")]
2
3use cu29_clock::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) => v.0.hash(hasher),
132 }
133 }
134}
135
136impl PartialEq for Value {
137 fn eq(&self, rhs: &Self) -> bool {
138 match (self, rhs) {
139 (&Value::Bool(v0), &Value::Bool(v1)) if v0 == v1 => true,
140 (&Value::U8(v0), &Value::U8(v1)) if v0 == v1 => true,
141 (&Value::U16(v0), &Value::U16(v1)) if v0 == v1 => true,
142 (&Value::U32(v0), &Value::U32(v1)) if v0 == v1 => true,
143 (&Value::U64(v0), &Value::U64(v1)) if v0 == v1 => true,
144 (&Value::I8(v0), &Value::I8(v1)) if v0 == v1 => true,
145 (&Value::I16(v0), &Value::I16(v1)) if v0 == v1 => true,
146 (&Value::I32(v0), &Value::I32(v1)) if v0 == v1 => true,
147 (&Value::I64(v0), &Value::I64(v1)) if v0 == v1 => true,
148 (&Value::F32(v0), &Value::F32(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
149 (&Value::F64(v0), &Value::F64(v1)) if OrderedFloat(v0) == OrderedFloat(v1) => true,
150 (&Value::Char(v0), &Value::Char(v1)) if v0 == v1 => true,
151 (Value::String(v0), Value::String(v1)) if v0 == v1 => true,
152 (&Value::Unit, &Value::Unit) => true,
153 (Value::Option(v0), Value::Option(v1)) if v0 == v1 => true,
154 (Value::Newtype(v0), Value::Newtype(v1)) if v0 == v1 => true,
155 (Value::Seq(v0), Value::Seq(v1)) if v0 == v1 => true,
156 (Value::Map(v0), Value::Map(v1)) if v0 == v1 => true,
157 (Value::Bytes(v0), Value::Bytes(v1)) if v0 == v1 => true,
158 (&Value::CuTime(v0), &Value::CuTime(v1)) if v0 == v1 => true,
159 _ => false,
160 }
161 }
162}
163
164impl Ord for Value {
165 fn cmp(&self, rhs: &Self) -> Ordering {
166 match (self, rhs) {
167 (&Value::Bool(v0), Value::Bool(v1)) => v0.cmp(v1),
168 (&Value::U8(v0), Value::U8(v1)) => v0.cmp(v1),
169 (&Value::U16(v0), Value::U16(v1)) => v0.cmp(v1),
170 (&Value::U32(v0), Value::U32(v1)) => v0.cmp(v1),
171 (&Value::U64(v0), Value::U64(v1)) => v0.cmp(v1),
172 (&Value::I8(v0), Value::I8(v1)) => v0.cmp(v1),
173 (&Value::I16(v0), Value::I16(v1)) => v0.cmp(v1),
174 (&Value::I32(v0), Value::I32(v1)) => v0.cmp(v1),
175 (&Value::I64(v0), Value::I64(v1)) => v0.cmp(v1),
176 (&Value::F32(v0), &Value::F32(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
177 (&Value::F64(v0), &Value::F64(v1)) => OrderedFloat(v0).cmp(&OrderedFloat(v1)),
178 (&Value::Char(v0), Value::Char(v1)) => v0.cmp(v1),
179 (Value::String(v0), Value::String(v1)) => v0.cmp(v1),
180 (&Value::Unit, &Value::Unit) => Ordering::Equal,
181 (Value::Option(v0), Value::Option(v1)) => v0.cmp(v1),
182 (Value::Newtype(v0), Value::Newtype(v1)) => v0.cmp(v1),
183 (Value::Seq(v0), Value::Seq(v1)) => v0.cmp(v1),
184 (Value::Map(v0), Value::Map(v1)) => v0.cmp(v1),
185 (Value::Bytes(v0), Value::Bytes(v1)) => v0.cmp(v1),
186 (&Value::CuTime(v0), &Value::CuTime(v1)) => v0.cmp(&v1),
187 (v0, v1) => v0.discriminant().cmp(&v1.discriminant()),
188 }
189 }
190}
191
192impl Value {
193 fn discriminant(&self) -> usize {
194 match *self {
195 Value::Bool(..) => 0,
196 Value::U8(..) => 1,
197 Value::U16(..) => 2,
198 Value::U32(..) => 3,
199 Value::U64(..) => 4,
200 Value::I8(..) => 5,
201 Value::I16(..) => 6,
202 Value::I32(..) => 7,
203 Value::I64(..) => 8,
204 Value::F32(..) => 9,
205 Value::F64(..) => 10,
206 Value::Char(..) => 11,
207 Value::String(..) => 12,
208 Value::Unit => 13,
209 Value::Option(..) => 14,
210 Value::Newtype(..) => 15,
211 Value::Seq(..) => 16,
212 Value::Map(..) => 17,
213 Value::Bytes(..) => 18,
214 Value::CuTime(..) => 32,
215 }
216 }
217
218 fn unexpected(&self) -> serde::de::Unexpected {
219 match *self {
220 Value::Bool(b) => serde::de::Unexpected::Bool(b),
221 Value::U8(n) => serde::de::Unexpected::Unsigned(n as u64),
222 Value::U16(n) => serde::de::Unexpected::Unsigned(n as u64),
223 Value::U32(n) => serde::de::Unexpected::Unsigned(n as u64),
224 Value::U64(n) => serde::de::Unexpected::Unsigned(n),
225 Value::I8(n) => serde::de::Unexpected::Signed(n as i64),
226 Value::I16(n) => serde::de::Unexpected::Signed(n as i64),
227 Value::I32(n) => serde::de::Unexpected::Signed(n as i64),
228 Value::I64(n) => serde::de::Unexpected::Signed(n),
229 Value::F32(n) => serde::de::Unexpected::Float(n as f64),
230 Value::F64(n) => serde::de::Unexpected::Float(n),
231 Value::Char(c) => serde::de::Unexpected::Char(c),
232 Value::String(ref s) => serde::de::Unexpected::Str(s),
233 Value::Unit => serde::de::Unexpected::Unit,
234 Value::Option(_) => serde::de::Unexpected::Option,
235 Value::Newtype(_) => serde::de::Unexpected::NewtypeStruct,
236 Value::Seq(_) => serde::de::Unexpected::Seq,
237 Value::Map(_) => serde::de::Unexpected::Map,
238 Value::Bytes(ref b) => serde::de::Unexpected::Bytes(b),
239 Value::CuTime(n) => serde::de::Unexpected::Unsigned(n.0),
240 }
241 }
242
243 pub fn deserialize_into<'de, T: Deserialize<'de>>(self) -> Result<T, DeserializerError> {
244 T::deserialize(self)
245 }
246}
247
248impl Eq for Value {}
249impl PartialOrd for Value {
250 fn partial_cmp(&self, rhs: &Self) -> Option<Ordering> {
251 Some(self.cmp(rhs))
252 }
253}
254
255#[cfg(test)]
256mod tests {
257 use super::*;
258 use bincode::config::standard;
259 use cu29_clock::RobotClock;
260 use serde_derive::{Deserialize, Serialize};
261 use std::time::Duration;
262
263 #[test]
264 fn de_smoke_test() {
265 let value = Value::Option(Some(Box::new(Value::Seq(vec![
267 Value::U16(8),
268 Value::Char('a'),
269 Value::F32(1.0),
270 Value::String("hello".into()),
271 Value::Map(
272 vec![
273 (Value::Bool(false), Value::Unit),
274 (
275 Value::Bool(true),
276 Value::Newtype(Box::new(Value::Bytes(b"hi".as_ref().into()))),
277 ),
278 ]
279 .into_iter()
280 .collect(),
281 ),
282 ]))));
283
284 let value_de = Value::deserialize(value.clone()).unwrap();
286 assert_eq!(value_de, value);
287 }
288
289 #[test]
290 fn ser_smoke_test() {
291 #[derive(Serialize)]
292 struct Foo {
293 a: u32,
294 b: String,
295 c: Vec<bool>,
296 }
297
298 let foo = Foo {
299 a: 15,
300 b: "hello".into(),
301 c: vec![true, false],
302 };
303
304 let expected = Value::Map(
305 vec![
306 (Value::String("a".into()), Value::U32(15)),
307 (Value::String("b".into()), Value::String("hello".into())),
308 (
309 Value::String("c".into()),
310 Value::Seq(vec![Value::Bool(true), Value::Bool(false)]),
311 ),
312 ]
313 .into_iter()
314 .collect(),
315 );
316
317 let value = to_value(&foo).unwrap();
318 assert_eq!(expected, value);
319 }
320
321 #[test]
322 fn deserialize_into_enum() {
323 #[derive(Deserialize, Debug, PartialEq, Eq)]
324 enum Foo {
325 Bar,
326 Baz(u8),
327 }
328
329 let value = Value::String("Bar".into());
330 assert_eq!(Foo::deserialize(value).unwrap(), Foo::Bar);
331
332 let value = Value::Map(
333 vec![(Value::String("Baz".into()), Value::U8(1))]
334 .into_iter()
335 .collect(),
336 );
337 assert_eq!(Foo::deserialize(value).unwrap(), Foo::Baz(1));
338 }
339
340 #[test]
341 fn serialize_from_enum() {
342 #[derive(Serialize)]
343 enum Foo {
344 Bar,
345 Baz(u8),
346 Qux { quux: u8 },
347 Corge(u8, u8),
348 }
349
350 let bar = Foo::Bar;
351 assert_eq!(to_value(&bar).unwrap(), Value::String("Bar".into()));
352
353 let baz = Foo::Baz(1);
354 assert_eq!(
355 to_value(&baz).unwrap(),
356 Value::Map(
357 vec![(Value::String("Baz".into()), Value::U8(1))]
358 .into_iter()
359 .collect(),
360 )
361 );
362
363 let qux = Foo::Qux { quux: 2 };
364 assert_eq!(
365 to_value(&qux).unwrap(),
366 Value::Map(
367 vec![(
368 Value::String("Qux".into()),
369 Value::Map(
370 vec![(Value::String("quux".into()), Value::U8(2))]
371 .into_iter()
372 .collect()
373 )
374 )]
375 .into_iter()
376 .collect()
377 )
378 );
379
380 let corge = Foo::Corge(3, 4);
381 assert_eq!(
382 to_value(&corge).unwrap(),
383 Value::Map(
384 vec![(
385 Value::String("Corge".into()),
386 Value::Seq(vec![Value::U8(3), Value::U8(4)])
387 )]
388 .into_iter()
389 .collect()
390 )
391 );
392 }
393
394 #[test]
395 fn deserialize_inside_deserialize_impl() {
396 #[derive(Debug, PartialEq, Eq)]
397 enum Event {
398 Added(u32),
399 Error(u8),
400 }
401
402 impl<'de> serde::Deserialize<'de> for Event {
403 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
404 where
405 D: serde::Deserializer<'de>,
406 {
407 #[derive(Deserialize)]
408 struct RawEvent {
409 kind: String,
410 object: Value,
411 }
412
413 let raw_event = RawEvent::deserialize(deserializer)?;
414
415 let object_deserializer = ValueDeserializer::new(raw_event.object);
418
419 Ok(match &*raw_event.kind {
420 "ADDED" => Event::Added(<_>::deserialize(object_deserializer)?),
421 "ERROR" => Event::Error(<_>::deserialize(object_deserializer)?),
422 kind => {
423 return Err(serde::de::Error::unknown_variant(kind, &["ADDED", "ERROR"]))
424 }
425 })
426 }
427 }
428
429 let input = Value::Map(
430 vec![
431 (
432 Value::String("kind".to_owned()),
433 Value::String("ADDED".to_owned()),
434 ),
435 (Value::String("object".to_owned()), Value::U32(5)),
436 ]
437 .into_iter()
438 .collect(),
439 );
440 let event = Event::deserialize(input).expect("could not deserialize ADDED event");
441 assert_eq!(event, Event::Added(5));
442
443 let input = Value::Map(
444 vec![
445 (
446 Value::String("kind".to_owned()),
447 Value::String("ERROR".to_owned()),
448 ),
449 (Value::String("object".to_owned()), Value::U8(5)),
450 ]
451 .into_iter()
452 .collect(),
453 );
454 let event = Event::deserialize(input).expect("could not deserialize ERROR event");
455 assert_eq!(event, Event::Error(5));
456
457 let input = Value::Map(
458 vec![
459 (
460 Value::String("kind".to_owned()),
461 Value::String("ADDED".to_owned()),
462 ),
463 (Value::String("object".to_owned()), Value::Unit),
464 ]
465 .into_iter()
466 .collect(),
467 );
468 let _ =
469 Event::deserialize(input).expect_err("expected deserializing bad ADDED event to fail");
470 }
471
472 #[test]
473 fn deserialize_newtype() {
474 #[derive(Debug, Deserialize, PartialEq)]
475 struct Foo(i32);
476
477 let input = Value::I32(5);
478 let foo = Foo::deserialize(input).unwrap();
479 assert_eq!(foo, Foo(5));
480 }
481
482 #[test]
483 fn deserialize_newtype2() {
484 #[derive(Debug, Deserialize, PartialEq)]
485 struct Foo(i32);
486
487 #[derive(Debug, Deserialize, PartialEq)]
488 struct Bar {
489 foo: Foo,
490 }
491
492 let input = Value::Map(
493 vec![(Value::String("foo".to_owned()), Value::I32(5))]
494 .into_iter()
495 .collect(),
496 );
497 let bar = Bar::deserialize(input).unwrap();
498 assert_eq!(bar, Bar { foo: Foo(5) });
499 }
500
501 #[test]
502 fn clock_ser_deser() {
503 let (clock, mock) = RobotClock::mock();
504 mock.increment(Duration::from_nanos(42));
505 let c = clock.now();
506
507 let input = Value::CuTime(c);
508 let foo = CuTime::deserialize(input).unwrap();
509 assert_eq!(foo, CuTime::from(Duration::from_nanos(42)));
510 }
511 #[test]
512 fn value_encode_decode() {
513 fn check_value(value: Value) {
514 let v = bincode::encode_to_vec(&value, standard()).expect("encode failed");
515 let (v2, s) = bincode::decode_from_slice::<Value, _>(v.as_slice(), standard())
516 .expect("decode failed");
517 assert_eq!(s, v.len());
518 assert_eq!(&v2, &value);
519 }
520
521 check_value(Value::Bool(true));
522 check_value(Value::U8(42));
523 check_value(Value::U16(42));
524 check_value(Value::U32(42));
525 check_value(Value::U64(42));
526 check_value(Value::I8(42));
527 check_value(Value::I16(42));
528 check_value(Value::I32(42));
529 check_value(Value::I64(42));
530 check_value(Value::F32(42.42));
531 check_value(Value::F64(42.42));
532 check_value(Value::Char('4'));
533 check_value(Value::String("42".into()));
534 check_value(Value::Unit);
535 check_value(Value::Option(Some(Box::new(Value::U32(42)))));
536 check_value(Value::Newtype(Box::new(Value::U32(42))));
537 check_value(Value::Seq(vec![Value::Bool(true), Value::U32(42)]));
538 check_value(Value::Map(BTreeMap::from([
539 (Value::Bool(true), Value::U32(42)),
540 (Value::String("42".into()), Value::I32(42)),
541 ])));
542 check_value(Value::Bytes(vec![0x4, 0x2]));
543 check_value(Value::CuTime(CuTime::from(Duration::from_nanos(42))));
544 }
545
546 #[test]
547 fn test_cutime_tovalue() {
548 let c = CuTime::from(Duration::from_nanos(42));
549 let v = to_value(c).expect("to_value failed");
550 assert_eq!(v, Value::CuTime(c));
551 }
552}