1#[cfg(test)]
5use std::collections::BTreeMap;
6use std::{fmt, vec};
7
8use serde::de::{
9 self, Deserialize, DeserializeOwned, DeserializeSeed, Deserializer, EnumAccess, MapAccess,
10 SeqAccess, Unexpected, VariantAccess, Visitor,
11};
12use serde::forward_to_deserialize_any;
13
14use crate::date::Date;
15use crate::depth::MAX_PARSE_DEPTH;
16use crate::error::{Error, Result};
17use crate::scalar;
18use crate::uid::Uid;
19use crate::value::ser::{
20 DATE_NEWTYPE, UID_NEWTYPE, format_sentinel_date, narrow_f32, parse_sentinel_date,
21};
22use crate::value::{Dictionary, Integer, Real, Value};
23
24pub fn from_value<T>(value: Value) -> Result<T>
48where
49 T: DeserializeOwned,
50{
51 T::deserialize(ValueDeserializer::new(value, false))
52}
53
54const fn guard_entry(depth: usize) -> Result<()> {
55 if depth > MAX_PARSE_DEPTH {
56 Err(Error::MaxDepthExceeded)
57 } else {
58 Ok(())
59 }
60}
61
62const fn guard_descent(depth: usize) -> Result<usize> {
65 if depth >= MAX_PARSE_DEPTH {
66 Err(Error::MaxDepthExceeded)
67 } else {
68 Ok(depth + 1)
69 }
70}
71
72fn unexpected_value(value: &Value) -> Unexpected<'_> {
73 match value {
74 Value::Dictionary(_) => Unexpected::Map,
75 Value::Array(_) => Unexpected::Seq,
76 Value::String(s) => Unexpected::Str(s),
77 Value::Integer(Integer::Signed(signed)) => Unexpected::Signed(*signed),
78 Value::Integer(Integer::Unsigned(unsigned)) => Unexpected::Unsigned(*unsigned),
79 Value::Real(real) => Unexpected::Float(real.value()),
80 Value::Boolean(b) => Unexpected::Bool(*b),
81 Value::Data(data) => Unexpected::Bytes(data),
82 Value::Date(_) => Unexpected::Other("date"),
83 Value::Uid(_) => Unexpected::Other("UID"),
84 }
85}
86
87fn visit_array<'de, V>(values: Vec<Value>, depth: usize, lax: bool, visitor: V) -> Result<V::Value>
88where
89 V: Visitor<'de>,
90{
91 let len = values.len();
92 let mut access = SeqAccessor {
93 iter: values.into_iter(),
94 depth,
95 lax,
96 };
97 let result = visitor.visit_seq(&mut access)?;
98 if access.iter.len() == 0 {
99 Ok(result)
100 } else {
101 Err(de::Error::invalid_length(len, &"fewer elements in array"))
102 }
103}
104
105fn visit_dictionary<'de, V>(
106 dict: Dictionary,
107 depth: usize,
108 lax: bool,
109 visitor: V,
110) -> Result<V::Value>
111where
112 V: Visitor<'de>,
113{
114 let len = dict.len();
115 let mut access = MapAccessor {
116 iter: dict.into_iter(),
117 pending_value: None,
118 depth,
119 lax,
120 };
121 let result = visitor.visit_map(&mut access)?;
122 if access.iter.len() == 0 && access.pending_value.is_none() {
123 Ok(result)
124 } else {
125 Err(de::Error::invalid_length(
126 len,
127 &"fewer entries in dictionary",
128 ))
129 }
130}
131
132pub(crate) struct ValueDeserializer {
139 value: Value,
140 depth: usize,
141 lax: bool,
142}
143
144impl ValueDeserializer {
145 pub(crate) const fn new(value: Value, lax: bool) -> Self {
148 Self {
149 value,
150 depth: 0,
151 lax,
152 }
153 }
154
155 const fn at(value: Value, depth: usize, lax: bool) -> Self {
156 Self { value, depth, lax }
157 }
158
159 fn integer_target<'de, V>(
160 self,
161 visitor: V,
162 expected: &'static str,
163 signed: bool,
164 ) -> Result<V::Value>
165 where
166 V: Visitor<'de>,
167 {
168 guard_entry(self.depth)?;
169 let found = self.value.type_name();
170 match self.value {
171 Value::Integer(Integer::Signed(value)) => visitor.visit_i64(value),
172 Value::Integer(Integer::Unsigned(value)) => visitor.visit_u64(value),
173 Value::Uid(uid) => visitor.visit_u64(uid.get()),
174 Value::String(s) if self.lax => {
175 if signed {
176 visitor.visit_i64(scalar::parse_i64(&s, 10)?)
177 } else {
178 visitor.visit_u64(scalar::parse_u64(&s, 10)?)
179 }
180 }
181 _ => Err(Error::TypeMismatch { expected, found }),
182 }
183 }
184
185 fn float_target<'de, V>(self, visitor: V, expected: &'static str) -> Result<V::Value>
186 where
187 V: Visitor<'de>,
188 {
189 guard_entry(self.depth)?;
190 let found = self.value.type_name();
191 match self.value {
192 Value::Real(real) => visitor.visit_f64(real.value()),
193 Value::String(s) if self.lax => visitor.visit_f64(scalar::parse_f64(&s)?),
194 _ => Err(Error::TypeMismatch { expected, found }),
195 }
196 }
197
198 fn string_target<'de, V>(self, visitor: V, expected: &'static str) -> Result<V::Value>
199 where
200 V: Visitor<'de>,
201 {
202 guard_entry(self.depth)?;
203 let found = self.value.type_name();
204 match self.value {
205 Value::String(s) => visitor.visit_string(s),
206 _ => Err(Error::TypeMismatch { expected, found }),
207 }
208 }
209
210 fn uid_sentinel<'de, V>(self, visitor: V) -> Result<V::Value>
212 where
213 V: Visitor<'de>,
214 {
215 let found = self.value.type_name();
216 match self.value {
217 Value::Uid(uid) => visitor.visit_u64(uid.get()),
218 Value::Integer(Integer::Signed(value)) if value < 0 => visitor.visit_i64(value),
219 Value::Integer(Integer::Signed(value)) => visitor.visit_u64(value.cast_unsigned()),
220 Value::Integer(Integer::Unsigned(value)) => visitor.visit_u64(value),
221 Value::String(s) if self.lax => visitor.visit_u64(scalar::parse_u64(&s, 10)?),
222 _ => Err(Error::TypeMismatch {
223 expected: "UID",
224 found,
225 }),
226 }
227 }
228
229 fn date_sentinel<'de, V>(self, visitor: V) -> Result<V::Value>
232 where
233 V: Visitor<'de>,
234 {
235 let found = self.value.type_name();
236 match self.value {
237 Value::Date(date) => visitor.visit_string(format_sentinel_date(date)),
238 Value::String(s) if self.lax => Date::parse_text_layout(&s).map_or_else(
239 || Err(Error::ParseScalar(format!("invalid date literal: {s}"))),
240 |date| visitor.visit_string(format_sentinel_date(date)),
241 ),
242 _ => Err(Error::TypeMismatch {
243 expected: "date",
244 found,
245 }),
246 }
247 }
248}
249
250macro_rules! deserialize_signed_integer {
251 ($($method:ident: $expected:literal,)*) => {$(
252 fn $method<V>(self, visitor: V) -> Result<V::Value>
253 where
254 V: Visitor<'de>,
255 {
256 self.integer_target(visitor, $expected, true)
257 }
258 )*};
259}
260
261macro_rules! deserialize_unsigned_integer {
262 ($($method:ident: $expected:literal,)*) => {$(
263 fn $method<V>(self, visitor: V) -> Result<V::Value>
264 where
265 V: Visitor<'de>,
266 {
267 self.integer_target(visitor, $expected, false)
268 }
269 )*};
270}
271
272impl<'de> Deserializer<'de> for ValueDeserializer {
273 type Error = Error;
274
275 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
276 where
277 V: Visitor<'de>,
278 {
279 guard_entry(self.depth)?;
280 let Self { value, depth, lax } = self;
281 match value {
282 Value::Dictionary(dict) => visit_dictionary(dict, guard_descent(depth)?, lax, visitor),
283 Value::Array(values) => visit_array(values, guard_descent(depth)?, lax, visitor),
284 Value::String(s) => visitor.visit_string(s),
286 Value::Integer(Integer::Signed(signed)) if signed < 0 => visitor.visit_i64(signed),
287 Value::Integer(Integer::Signed(signed)) => visitor.visit_u64(signed.cast_unsigned()),
288 Value::Integer(Integer::Unsigned(unsigned)) => visitor.visit_u64(unsigned),
289 Value::Real(real) if real.wide() => visitor.visit_f64(real.value()),
290 Value::Real(real) => visitor.visit_f32(narrow_f32(real)),
291 Value::Boolean(b) => visitor.visit_bool(b),
292 Value::Data(data) => visitor.visit_byte_buf(data),
293 Value::Date(date) => visitor.visit_newtype_struct(DatePayloadDeserializer { date }),
294 Value::Uid(uid) => visitor.visit_newtype_struct(UidPayloadDeserializer { uid }),
295 }
296 }
297
298 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
299 where
300 V: Visitor<'de>,
301 {
302 guard_entry(self.depth)?;
303 let found = self.value.type_name();
304 match self.value {
305 Value::Boolean(b) => visitor.visit_bool(b),
306 Value::String(s) if self.lax => visitor.visit_bool(scalar::parse_bool(&s)?),
307 _ => Err(Error::TypeMismatch {
308 expected: "bool",
309 found,
310 }),
311 }
312 }
313
314 deserialize_signed_integer! {
315 deserialize_i8: "i8",
316 deserialize_i16: "i16",
317 deserialize_i32: "i32",
318 deserialize_i64: "i64",
319 deserialize_i128: "i128",
320 }
321
322 deserialize_unsigned_integer! {
323 deserialize_u8: "u8",
324 deserialize_u16: "u16",
325 deserialize_u32: "u32",
326 deserialize_u64: "u64",
327 deserialize_u128: "u128",
328 }
329
330 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
331 where
332 V: Visitor<'de>,
333 {
334 self.float_target(visitor, "f32")
335 }
336
337 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
338 where
339 V: Visitor<'de>,
340 {
341 self.float_target(visitor, "f64")
342 }
343
344 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
345 where
346 V: Visitor<'de>,
347 {
348 self.string_target(visitor, "char")
349 }
350
351 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
352 where
353 V: Visitor<'de>,
354 {
355 self.string_target(visitor, "string")
356 }
357
358 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
359 where
360 V: Visitor<'de>,
361 {
362 self.string_target(visitor, "string")
363 }
364
365 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
366 where
367 V: Visitor<'de>,
368 {
369 guard_entry(self.depth)?;
370 let Self { value, depth, lax } = self;
371 let found = value.type_name();
372 match value {
373 Value::Data(data) => visitor.visit_byte_buf(data),
374 Value::Array(values) => visit_array(values, guard_descent(depth)?, lax, visitor),
375 _ => Err(Error::TypeMismatch {
377 expected: "bytes",
378 found,
379 }),
380 }
381 }
382
383 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
384 where
385 V: Visitor<'de>,
386 {
387 self.deserialize_bytes(visitor)
388 }
389
390 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
391 where
392 V: Visitor<'de>,
393 {
394 guard_entry(self.depth)?;
395 visitor.visit_some(self)
396 }
397
398 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
399 where
400 V: Visitor<'de>,
401 {
402 guard_entry(self.depth)?;
403 drop(visitor);
404 Err(Error::TypeMismatch {
405 expected: "unit",
406 found: self.value.type_name(),
407 })
408 }
409
410 fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
411 where
412 V: Visitor<'de>,
413 {
414 guard_entry(self.depth)?;
415 drop(visitor);
416 Err(Error::TypeMismatch {
417 expected: name,
418 found: self.value.type_name(),
419 })
420 }
421
422 fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
423 where
424 V: Visitor<'de>,
425 {
426 guard_entry(self.depth)?;
427 match name {
428 UID_NEWTYPE => self.uid_sentinel(visitor),
429 DATE_NEWTYPE => self.date_sentinel(visitor),
430 _ => visitor.visit_newtype_struct(self),
431 }
432 }
433
434 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
435 where
436 V: Visitor<'de>,
437 {
438 guard_entry(self.depth)?;
439 let Self { value, depth, lax } = self;
440 let found = value.type_name();
441 match value {
442 Value::Array(values) => visit_array(values, guard_descent(depth)?, lax, visitor),
443 Value::Data(data) => {
445 let bytes = data
446 .into_iter()
447 .map(|byte| Value::Integer(Integer::from(byte)))
448 .collect();
449 visit_array(bytes, depth, lax, visitor)
450 }
451 _ => Err(Error::TypeMismatch {
452 expected: "sequence",
453 found,
454 }),
455 }
456 }
457
458 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
459 where
460 V: Visitor<'de>,
461 {
462 self.deserialize_seq(visitor)
463 }
464
465 fn deserialize_tuple_struct<V>(
466 self,
467 _name: &'static str,
468 _len: usize,
469 visitor: V,
470 ) -> Result<V::Value>
471 where
472 V: Visitor<'de>,
473 {
474 self.deserialize_seq(visitor)
475 }
476
477 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
478 where
479 V: Visitor<'de>,
480 {
481 guard_entry(self.depth)?;
482 let Self { value, depth, lax } = self;
483 let found = value.type_name();
484 match value {
485 Value::Dictionary(dict) => visit_dictionary(dict, guard_descent(depth)?, lax, visitor),
486 _ => Err(Error::TypeMismatch {
487 expected: "map",
488 found,
489 }),
490 }
491 }
492
493 fn deserialize_struct<V>(
494 self,
495 name: &'static str,
496 _fields: &'static [&'static str],
497 visitor: V,
498 ) -> Result<V::Value>
499 where
500 V: Visitor<'de>,
501 {
502 guard_entry(self.depth)?;
503 let Self { value, depth, lax } = self;
504 let found = value.type_name();
505 match value {
506 Value::Dictionary(dict) => visit_dictionary(dict, guard_descent(depth)?, lax, visitor),
507 _ => Err(Error::TypeMismatch {
508 expected: name,
509 found,
510 }),
511 }
512 }
513
514 fn deserialize_enum<V>(
515 self,
516 name: &'static str,
517 _variants: &'static [&'static str],
518 visitor: V,
519 ) -> Result<V::Value>
520 where
521 V: Visitor<'de>,
522 {
523 guard_entry(self.depth)?;
524 let Self { value, depth, lax } = self;
525 let found = value.type_name();
526 match value {
527 Value::String(variant) => visitor.visit_enum(EnumDeserializer {
528 variant,
529 payload: None,
530 depth,
531 lax,
532 }),
533 Value::Dictionary(dict) => {
534 let depth = guard_descent(depth)?;
535 let mut entries = dict.into_iter();
536 match (entries.next(), entries.next()) {
537 (Some((variant, payload)), None) => visitor.visit_enum(EnumDeserializer {
538 variant,
539 payload: Some(payload),
540 depth,
541 lax,
542 }),
543 _ => Err(Error::Message(
544 "expected a single-key dictionary for an enum variant".to_owned(),
545 )),
546 }
547 }
548 _ => Err(Error::TypeMismatch {
549 expected: name,
550 found,
551 }),
552 }
553 }
554
555 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
556 where
557 V: Visitor<'de>,
558 {
559 self.string_target(visitor, "identifier")
560 }
561
562 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
563 where
564 V: Visitor<'de>,
565 {
566 self.deserialize_any(visitor)
567 }
568
569 fn is_human_readable(&self) -> bool {
570 true
571 }
572}
573
574struct SeqAccessor {
575 iter: vec::IntoIter<Value>,
576 depth: usize,
577 lax: bool,
578}
579
580impl<'de> SeqAccess<'de> for SeqAccessor {
581 type Error = Error;
582
583 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
584 where
585 T: DeserializeSeed<'de>,
586 {
587 self.iter.next().map_or(Ok(None), |value| {
588 seed.deserialize(ValueDeserializer::at(value, self.depth, self.lax))
589 .map(Some)
590 })
591 }
592
593 fn size_hint(&self) -> Option<usize> {
594 Some(self.iter.len())
595 }
596}
597
598struct MapAccessor {
599 iter: indexmap::map::IntoIter<String, Value>,
600 pending_value: Option<Value>,
601 depth: usize,
602 lax: bool,
603}
604
605impl<'de> MapAccess<'de> for MapAccessor {
606 type Error = Error;
607
608 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
609 where
610 K: DeserializeSeed<'de>,
611 {
612 self.iter.next().map_or(Ok(None), |(key, value)| {
613 self.pending_value = Some(value);
614 seed.deserialize(ValueDeserializer::at(Value::String(key), self.depth, false))
616 .map(Some)
617 })
618 }
619
620 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
621 where
622 V: DeserializeSeed<'de>,
623 {
624 self.pending_value.take().map_or_else(
625 || {
626 Err(Error::Message(
627 "map value requested before its key".to_owned(),
628 ))
629 },
630 |value| seed.deserialize(ValueDeserializer::at(value, self.depth, self.lax)),
631 )
632 }
633
634 fn size_hint(&self) -> Option<usize> {
635 Some(
636 self.iter
637 .len()
638 .saturating_add(usize::from(self.pending_value.is_some())),
639 )
640 }
641}
642
643struct EnumDeserializer {
644 variant: String,
645 payload: Option<Value>,
646 depth: usize,
647 lax: bool,
648}
649
650impl<'de> EnumAccess<'de> for EnumDeserializer {
651 type Error = Error;
652 type Variant = VariantDeserializer;
653
654 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, VariantDeserializer)>
655 where
656 V: DeserializeSeed<'de>,
657 {
658 let variant = seed.deserialize(ValueDeserializer::at(
659 Value::String(self.variant),
660 self.depth,
661 self.lax,
662 ))?;
663 Ok((
664 variant,
665 VariantDeserializer {
666 payload: self.payload,
667 depth: self.depth,
668 lax: self.lax,
669 },
670 ))
671 }
672}
673
674struct VariantDeserializer {
675 payload: Option<Value>,
676 depth: usize,
677 lax: bool,
678}
679
680impl<'de> VariantAccess<'de> for VariantDeserializer {
681 type Error = Error;
682
683 fn unit_variant(self) -> Result<()> {
684 self.payload.map_or(Ok(()), |value| {
685 Err(de::Error::invalid_type(
686 unexpected_value(&value),
687 &"unit variant",
688 ))
689 })
690 }
691
692 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
693 where
694 T: DeserializeSeed<'de>,
695 {
696 self.payload.map_or_else(
697 || {
698 Err(de::Error::invalid_type(
699 Unexpected::UnitVariant,
700 &"newtype variant",
701 ))
702 },
703 |value| seed.deserialize(ValueDeserializer::at(value, self.depth, self.lax)),
704 )
705 }
706
707 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
708 where
709 V: Visitor<'de>,
710 {
711 match self.payload {
712 Some(Value::Array(values)) => {
713 visit_array(values, guard_descent(self.depth)?, self.lax, visitor)
714 }
715 Some(other) => Err(de::Error::invalid_type(
716 unexpected_value(&other),
717 &"tuple variant",
718 )),
719 None => Err(de::Error::invalid_type(
720 Unexpected::UnitVariant,
721 &"tuple variant",
722 )),
723 }
724 }
725
726 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
727 where
728 V: Visitor<'de>,
729 {
730 match self.payload {
731 Some(Value::Dictionary(dict)) => {
732 visit_dictionary(dict, guard_descent(self.depth)?, self.lax, visitor)
733 }
734 Some(other) => Err(de::Error::invalid_type(
735 unexpected_value(&other),
736 &"struct variant",
737 )),
738 None => Err(de::Error::invalid_type(
739 Unexpected::UnitVariant,
740 &"struct variant",
741 )),
742 }
743 }
744}
745
746struct DatePayloadDeserializer {
751 date: Date,
752}
753
754impl<'de> Deserializer<'de> for DatePayloadDeserializer {
755 type Error = Error;
756
757 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
758 where
759 V: Visitor<'de>,
760 {
761 visitor.visit_string(format_sentinel_date(self.date))
762 }
763
764 forward_to_deserialize_any! {
765 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf
766 option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier
767 ignored_any
768 }
769}
770
771struct UidPayloadDeserializer {
774 uid: Uid,
775}
776
777impl<'de> Deserializer<'de> for UidPayloadDeserializer {
778 type Error = Error;
779
780 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
781 where
782 V: Visitor<'de>,
783 {
784 visitor.visit_u64(self.uid.get())
785 }
786
787 forward_to_deserialize_any! {
788 bool i8 i16 i32 i64 i128 u8 u16 u32 u64 u128 f32 f64 char str string bytes byte_buf
789 option unit unit_struct newtype_struct seq tuple tuple_struct map struct enum identifier
790 ignored_any
791 }
792}
793
794struct ValueVisitor;
795
796impl<'de> Visitor<'de> for ValueVisitor {
797 type Value = Value;
798
799 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
800 formatter.write_str("any property-list value")
801 }
802
803 fn visit_bool<E>(self, value: bool) -> Result<Value, E> {
804 Ok(Value::Boolean(value))
805 }
806
807 fn visit_i64<E>(self, value: i64) -> Result<Value, E> {
808 Ok(Value::Integer(Integer::Signed(value)))
809 }
810
811 fn visit_u64<E>(self, value: u64) -> Result<Value, E> {
812 Ok(Value::Integer(Integer::Unsigned(value)))
813 }
814
815 fn visit_i128<E>(self, value: i128) -> Result<Value, E>
816 where
817 E: de::Error,
818 {
819 i64::try_from(value)
820 .map(|signed| Value::Integer(Integer::Signed(signed)))
821 .or_else(|_| {
822 u64::try_from(value).map(|unsigned| Value::Integer(Integer::Unsigned(unsigned)))
823 })
824 .map_err(|_| E::custom("integer does not fit the 64-bit property-list range"))
825 }
826
827 fn visit_u128<E>(self, value: u128) -> Result<Value, E>
828 where
829 E: de::Error,
830 {
831 u64::try_from(value)
832 .map(|unsigned| Value::Integer(Integer::Unsigned(unsigned)))
833 .map_err(|_| E::custom("integer does not fit the 64-bit property-list range"))
834 }
835
836 fn visit_f32<E>(self, value: f32) -> Result<Value, E> {
837 Ok(Value::Real(Real::from(value)))
838 }
839
840 fn visit_f64<E>(self, value: f64) -> Result<Value, E> {
841 Ok(Value::Real(Real::from(value)))
842 }
843
844 fn visit_char<E>(self, value: char) -> Result<Value, E> {
845 Ok(Value::String(value.to_string()))
846 }
847
848 fn visit_str<E>(self, value: &str) -> Result<Value, E> {
849 Ok(Value::String(value.to_owned()))
850 }
851
852 fn visit_string<E>(self, value: String) -> Result<Value, E> {
853 Ok(Value::String(value))
854 }
855
856 fn visit_bytes<E>(self, value: &[u8]) -> Result<Value, E> {
857 Ok(Value::Data(value.to_vec()))
858 }
859
860 fn visit_byte_buf<E>(self, value: Vec<u8>) -> Result<Value, E> {
861 Ok(Value::Data(value))
862 }
863
864 fn visit_some<D>(self, deserializer: D) -> Result<Value, D::Error>
865 where
866 D: Deserializer<'de>,
867 {
868 Value::deserialize(deserializer)
869 }
870
871 fn visit_seq<A>(self, mut seq: A) -> Result<Value, A::Error>
872 where
873 A: SeqAccess<'de>,
874 {
875 let mut values = Vec::new();
876 while let Some(element) = seq.next_element()? {
877 values.push(element);
878 }
879 Ok(Value::Array(values))
880 }
881
882 fn visit_map<A>(self, mut map: A) -> Result<Value, A::Error>
883 where
884 A: MapAccess<'de>,
885 {
886 let mut dict = Dictionary::new();
887 while let Some((key, value)) = map.next_entry::<String, Self::Value>()? {
888 drop(dict.insert(key, value));
889 }
890 Ok(Value::Dictionary(dict))
891 }
892
893 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Value, D::Error>
897 where
898 D: Deserializer<'de>,
899 {
900 match Value::deserialize(deserializer)? {
901 Value::Integer(integer) => integer.as_unsigned().map_or_else(
902 || {
903 Err(de::Error::custom(
904 "uid sentinel payload must be an unsigned integer",
905 ))
906 },
907 |uid| Ok(Value::Uid(Uid::from(uid))),
908 ),
909 Value::String(payload) => {
910 parse_sentinel_date(&payload)
911 .map(Value::Date)
912 .ok_or_else(|| {
913 de::Error::invalid_value(
914 Unexpected::Str(&payload),
915 &"an rfc 3339 date sentinel payload",
916 )
917 })
918 }
919 other => Err(de::Error::invalid_type(
920 unexpected_value(&other),
921 &"a UID or date sentinel payload",
922 )),
923 }
924 }
925}
926
927impl<'de> Deserialize<'de> for Value {
928 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
929 where
930 D: Deserializer<'de>,
931 {
932 deserializer.deserialize_any(ValueVisitor)
933 }
934}
935
936struct IntegerVisitor;
937
938impl Visitor<'_> for IntegerVisitor {
939 type Value = Integer;
940
941 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
942 formatter.write_str("a property-list integer")
943 }
944
945 fn visit_i64<E>(self, value: i64) -> Result<Integer, E> {
946 Ok(Integer::Signed(value))
947 }
948
949 fn visit_u64<E>(self, value: u64) -> Result<Integer, E> {
950 Ok(Integer::Unsigned(value))
951 }
952
953 fn visit_i128<E>(self, value: i128) -> Result<Integer, E>
954 where
955 E: de::Error,
956 {
957 i64::try_from(value)
958 .map(Integer::Signed)
959 .or_else(|_| u64::try_from(value).map(Integer::Unsigned))
960 .map_err(|_| E::custom("integer does not fit the 64-bit property-list range"))
961 }
962
963 fn visit_u128<E>(self, value: u128) -> Result<Integer, E>
964 where
965 E: de::Error,
966 {
967 u64::try_from(value)
968 .map(Integer::Unsigned)
969 .map_err(|_| E::custom("integer does not fit the 64-bit property-list range"))
970 }
971}
972
973impl<'de> Deserialize<'de> for Integer {
974 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
975 where
976 D: Deserializer<'de>,
977 {
978 deserializer.deserialize_any(IntegerVisitor)
979 }
980}
981
982struct RealVisitor;
983
984impl Visitor<'_> for RealVisitor {
985 type Value = Real;
986
987 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
988 formatter.write_str("a property-list real")
989 }
990
991 fn visit_f32<E>(self, value: f32) -> Result<Real, E> {
992 Ok(Real::from(value))
993 }
994
995 fn visit_f64<E>(self, value: f64) -> Result<Real, E> {
996 Ok(Real::from(value))
997 }
998}
999
1000impl<'de> Deserialize<'de> for Real {
1001 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1002 where
1003 D: Deserializer<'de>,
1004 {
1005 deserializer.deserialize_any(RealVisitor)
1006 }
1007}
1008
1009struct UidVisitor;
1010
1011impl<'de> Visitor<'de> for UidVisitor {
1012 type Value = Uid;
1013
1014 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1015 formatter.write_str("an unsigned integer UID")
1016 }
1017
1018 fn visit_u64<E>(self, value: u64) -> Result<Uid, E> {
1019 Ok(Uid::from(value))
1020 }
1021
1022 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Uid, D::Error>
1023 where
1024 D: Deserializer<'de>,
1025 {
1026 deserializer.deserialize_u64(self)
1027 }
1028}
1029
1030impl<'de> Deserialize<'de> for Uid {
1031 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1032 where
1033 D: Deserializer<'de>,
1034 {
1035 deserializer.deserialize_newtype_struct(UID_NEWTYPE, UidVisitor)
1036 }
1037}
1038
1039struct DateVisitor;
1040
1041impl<'de> Visitor<'de> for DateVisitor {
1042 type Value = Date;
1043
1044 fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
1045 formatter.write_str("an rfc 3339 date string")
1046 }
1047
1048 fn visit_str<E>(self, value: &str) -> Result<Date, E>
1049 where
1050 E: de::Error,
1051 {
1052 parse_sentinel_date(value).ok_or_else(|| E::invalid_value(Unexpected::Str(value), &self))
1053 }
1054
1055 fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Date, D::Error>
1056 where
1057 D: Deserializer<'de>,
1058 {
1059 deserializer.deserialize_str(self)
1060 }
1061}
1062
1063impl<'de> Deserialize<'de> for Date {
1064 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
1065 where
1066 D: Deserializer<'de>,
1067 {
1068 deserializer.deserialize_newtype_struct(DATE_NEWTYPE, DateVisitor)
1069 }
1070}
1071
1072#[cfg(test)]
1073mod tests {
1074 #![expect(
1075 clippy::unwrap_used,
1076 clippy::panic,
1077 reason = "test code: unwrap/panic are the assertions"
1078 )]
1079
1080 use serde::{Deserialize, Serialize};
1081
1082 use super::*;
1083 use crate::value::ser::to_value;
1084
1085 fn dict<const N: usize>(entries: [(&str, Value); N]) -> Value {
1086 entries
1087 .into_iter()
1088 .map(|(key, value)| (key.to_owned(), value))
1089 .collect()
1090 }
1091
1092 fn rfc(s: &str) -> Date {
1093 Date::parse_rfc3339(s).unwrap()
1094 }
1095
1096 fn lax<T: DeserializeOwned>(value: Value) -> Result<T> {
1097 T::deserialize(ValueDeserializer::new(value, true))
1098 }
1099
1100 fn nested_arrays(containers: usize) -> Value {
1101 let mut value = Value::Array(Vec::new());
1102 for _ in 1..containers {
1103 value = Value::Array(vec![value]);
1104 }
1105 value
1106 }
1107
1108 #[test]
1109 fn derived_struct_round_trips_with_attributes() {
1110 #[derive(Serialize, Deserialize, PartialEq, Debug, Default)]
1111 struct Inner {
1112 count: u32,
1113 }
1114
1115 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1116 struct Pet {
1117 #[serde(rename = "Name")]
1118 name: String,
1119 #[serde(skip)]
1120 mood: u8,
1121 legs: Option<u32>,
1122 #[serde(default)]
1123 tag: String,
1124 nested: Inner,
1125 }
1126
1127 let pet = Pet {
1128 name: "Fido".to_owned(),
1129 mood: 0,
1130 legs: Some(4),
1131 tag: String::new(),
1132 nested: Inner { count: 2 },
1133 };
1134 let value = to_value(&pet).unwrap();
1135 assert_eq!(
1136 value,
1137 dict([
1138 ("Name", Value::from("Fido")),
1139 ("legs", Value::from(4u32)),
1140 ("nested", dict([("count", Value::from(2u32))])),
1141 ("tag", Value::from("")),
1142 ])
1143 );
1144 assert_eq!(from_value::<Pet>(value).unwrap(), pet);
1145
1146 let sparse = dict([
1148 ("Name", Value::from("Rex")),
1149 ("nested", dict([("count", Value::from(0u32))])),
1150 ]);
1151 assert_eq!(
1152 from_value::<Pet>(sparse).unwrap(),
1153 Pet {
1154 name: "Rex".to_owned(),
1155 mood: 0,
1156 legs: None,
1157 tag: String::new(),
1158 nested: Inner { count: 0 },
1159 }
1160 );
1161 }
1162
1163 #[test]
1164 fn missing_keys_error_without_option_or_default() {
1165 #[derive(Deserialize, Debug)]
1166 struct Strict {
1167 #[expect(dead_code, reason = "field exists only to be required")]
1168 required: i64,
1169 }
1170 assert!(from_value::<Strict>(dict([])).is_err());
1171 assert!(from_value::<Strict>(dict([("required", Value::from(1u8))])).is_ok());
1172 }
1173
1174 #[test]
1175 fn extra_keys_are_ignored_even_when_they_hold_dates() {
1176 #[derive(Deserialize, PartialEq, Debug)]
1177 struct Small {
1178 x: i64,
1179 }
1180 let value = dict([
1181 ("ignored", Value::Date(rfc("2013-11-27T00:34:00Z"))),
1182 ("uid_too", Value::Uid(Uid::from(3))),
1183 ("x", Value::from(1u8)),
1184 ]);
1185 assert_eq!(from_value::<Small>(value).unwrap(), Small { x: 1 });
1186
1187 let ignored = de::IgnoredAny::deserialize(ValueDeserializer::new(
1188 Value::Date(rfc("2013-11-27T00:34:00Z")),
1189 false,
1190 ));
1191 assert!(ignored.is_ok());
1192 }
1193
1194 #[test]
1195 fn flatten_round_trips_and_collisions_keep_the_last_writer() {
1196 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1197 struct Outer {
1198 a: u8,
1199 #[serde(flatten)]
1200 rest: BTreeMap<String, u8>,
1201 }
1202
1203 let outer = Outer {
1204 a: 1,
1205 rest: BTreeMap::from([("b".to_owned(), 2u8)]),
1206 };
1207 let value = to_value(&outer).unwrap();
1208 assert_eq!(
1209 value,
1210 dict([("a", Value::from(1u8)), ("b", Value::from(2u8))])
1211 );
1212 assert_eq!(from_value::<Outer>(value).unwrap(), outer);
1213
1214 let colliding = Outer {
1217 a: 1,
1218 rest: BTreeMap::from([("a".to_owned(), 9u8)]),
1219 };
1220 let wire = to_value(&colliding).unwrap();
1221 assert_eq!(wire, dict([("a", Value::from(9u8))]));
1222 assert_eq!(
1223 from_value::<Outer>(wire).unwrap(),
1224 Outer {
1225 a: 9,
1226 rest: BTreeMap::new(),
1227 }
1228 );
1229 }
1230
1231 #[test]
1232 fn illegal_strict_decodes_error() {
1233 assert!(from_value::<i64>(Value::from("abc")).is_err());
1235 assert!(from_value::<i64>(Value::Data(vec![0, 16, 4])).is_err());
1236 assert!(from_value::<i64>(Value::from(34.1)).is_err());
1237 assert!(from_value::<i64>(Value::from(true)).is_err());
1238 assert!(from_value::<i64>(Value::Date(rfc("2010-01-01T00:00:00Z"))).is_err());
1239 assert!(from_value::<bool>(Value::from(0u8)).is_err());
1240 assert!(from_value::<bool>(Value::from(vec![Value::from(0u8)])).is_err());
1241 assert!(from_value::<bool>(dict([("a", Value::from(0u8))])).is_err());
1242 assert!(
1243 from_value::<[i32; 1]>(Value::from(vec![
1244 Value::from(true),
1245 Value::from(true),
1246 Value::from(true),
1247 ]))
1248 .is_err()
1249 );
1250 assert!(from_value::<[u8; 3]>(Value::Data(b"Hello".to_vec())).is_err());
1251 }
1252
1253 #[test]
1254 fn integers_never_coerce_to_floats_but_reals_downcast() {
1255 assert!(matches!(
1256 from_value::<f64>(Value::from(5u8)),
1257 Err(Error::TypeMismatch {
1258 expected: "f64",
1259 found: "integer",
1260 })
1261 ));
1262 assert!(from_value::<f32>(Value::from(-5i64)).is_err());
1263
1264 let downcast = from_value::<f32>(Value::from(34.1)).unwrap();
1265 assert!((f64::from(downcast) - 34.1).abs() < 1e-4);
1266 let narrow = from_value::<f32>(Value::Real(Real::from(1.5f32))).unwrap();
1267 assert!((narrow - 1.5).abs() < f32::EPSILON);
1268 }
1269
1270 #[test]
1271 fn data_decodes_into_byte_shapes_but_never_strings() {
1272 assert_eq!(
1273 from_value::<Vec<u8>>(Value::Data(b"Hello".to_vec())).unwrap(),
1274 b"Hello".to_vec()
1275 );
1276 assert_eq!(
1277 from_value::<[u8; 5]>(Value::Data(b"Hello".to_vec())).unwrap(),
1278 *b"Hello"
1279 );
1280 assert!(from_value::<[u8; 8]>(Value::Data(b"Hello".to_vec())).is_err());
1281 assert!(from_value::<String>(Value::Data(b"Hello".to_vec())).is_err());
1282 assert!(lax::<String>(Value::Data(b"Hello".to_vec())).is_err());
1283
1284 let array = Value::from(vec![Value::from(1u8), Value::from(2u8)]);
1286 assert_eq!(from_value::<Vec<u8>>(array.clone()).unwrap(), vec![1, 2]);
1287 assert_eq!(from_value::<[u8; 2]>(array).unwrap(), [1, 2]);
1288 let too_big = Value::from(vec![Value::from(256u16)]);
1289 assert!(from_value::<Vec<u8>>(too_big).is_err());
1290
1291 assert!(from_value::<Vec<u8>>(Value::from("jkl")).is_err());
1293 assert!(lax::<Vec<u8>>(Value::from("jkl")).is_err());
1294 }
1295
1296 #[test]
1297 fn date_sources_decode_only_into_dates_and_values() {
1298 let date = rfc("2013-11-27T00:34:00.5Z");
1299 let value = Value::Date(date);
1300 assert_eq!(from_value::<Date>(value.clone()).unwrap(), date);
1301 assert_eq!(from_value::<Value>(value.clone()).unwrap(), value);
1302
1303 assert!(from_value::<String>(value.clone()).is_err());
1304 assert!(from_value::<u64>(value.clone()).is_err());
1305 assert!(from_value::<f64>(value.clone()).is_err());
1306 assert!(from_value::<BTreeMap<String, Value>>(value.clone()).is_err());
1307 assert!(from_value::<Vec<Value>>(value).is_err());
1308
1309 assert!(from_value::<Date>(Value::from("2013-11-27T00:34:00Z")).is_err());
1311
1312 let ancient = Date::from_apple_epoch(-1e300);
1313 assert_eq!(
1314 from_value::<Value>(Value::Date(ancient)).unwrap(),
1315 Value::Date(ancient)
1316 );
1317 }
1318
1319 #[test]
1320 fn uid_sources_downgrade_into_integers_but_not_strings_or_floats() {
1321 let value = Value::Uid(Uid::from(1024));
1322 assert_eq!(from_value::<Uid>(value.clone()).unwrap(), Uid::from(1024));
1323 assert_eq!(from_value::<u64>(value.clone()).unwrap(), 1024);
1324 assert_eq!(from_value::<i64>(value.clone()).unwrap(), 1024);
1325 assert_eq!(from_value::<Value>(value.clone()).unwrap(), value);
1326 assert!(from_value::<String>(value.clone()).is_err());
1327 assert!(from_value::<f64>(value).is_err());
1328
1329 assert!(from_value::<u8>(Value::Uid(Uid::from(1024))).is_err());
1331 assert!(from_value::<i64>(Value::Uid(Uid::from(u64::MAX))).is_err());
1332 }
1333
1334 #[test]
1335 fn integers_and_lax_strings_decode_into_uid_targets() {
1336 assert_eq!(
1337 from_value::<Uid>(Value::from(1024u64)).unwrap(),
1338 Uid::from(1024)
1339 );
1340 assert_eq!(
1341 from_value::<Uid>(Value::from(1024i64)).unwrap(),
1342 Uid::from(1024)
1343 );
1344 assert!(from_value::<Uid>(Value::from(-1i64)).is_err());
1345 assert!(from_value::<Uid>(Value::from("12")).is_err());
1346 assert_eq!(lax::<Uid>(Value::from("12")).unwrap(), Uid::from(12));
1347 assert!(lax::<Uid>(Value::from("+5")).is_err());
1348 assert!(from_value::<Uid>(Value::from(1.5)).is_err());
1349 }
1350
1351 #[test]
1352 fn integer_narrowing_is_range_checked() {
1353 assert!(from_value::<i64>(Value::from(u64::MAX)).is_err());
1354 assert!(from_value::<i8>(Value::from(300u16)).is_err());
1355 assert!(from_value::<u64>(Value::from(-1i8)).is_err());
1356 assert_eq!(from_value::<i64>(Value::from(5u64)).unwrap(), 5);
1357 assert_eq!(from_value::<u64>(Value::from(5i64)).unwrap(), 5);
1358 assert_eq!(from_value::<i8>(Value::from(-128i64)).unwrap(), i8::MIN);
1359 }
1360
1361 #[test]
1362 fn int128_targets_fit_or_error() {
1363 assert_eq!(
1364 from_value::<i128>(Value::from(u64::MAX)).unwrap(),
1365 i128::from(u64::MAX)
1366 );
1367 assert_eq!(from_value::<u128>(Value::from(7u8)).unwrap(), 7);
1368 assert!(from_value::<u128>(Value::from(-1i64)).is_err());
1369 assert_eq!(from_value::<i128>(Value::from(-1i64)).unwrap(), -1);
1370 }
1371
1372 #[test]
1373 fn value_round_trip_is_lossless_for_every_variant() {
1374 let tree = dict([
1375 (
1376 "array",
1377 Value::from(vec![
1378 Value::from(-1i64),
1379 Value::from(u64::MAX),
1380 dict([("inner", Value::from(false))]),
1381 ]),
1382 ),
1383 ("bool", Value::from(true)),
1384 ("data", Value::Data(vec![1, 2, 3])),
1385 ("date", Value::Date(rfc("2013-11-27T00:34:00.123456789Z"))),
1386 ("narrow", Value::Real(Real::from(32.5f32))),
1387 ("string", Value::from("hello")),
1388 ("uid", Value::Uid(Uid::from(u64::MAX))),
1389 ("wide", Value::from(1.5)),
1390 ]);
1391 let round_tripped = from_value::<Value>(tree.clone()).unwrap();
1392 assert_eq!(round_tripped, tree);
1393
1394 match round_tripped.as_dictionary().and_then(|d| d.get("narrow")) {
1397 Some(Value::Real(real)) => assert!(!real.wide()),
1398 other => panic!("expected a real, got {other:?}"),
1399 }
1400 match round_tripped.as_dictionary().and_then(|d| d.get("wide")) {
1401 Some(Value::Real(real)) => assert!(real.wide()),
1402 other => panic!("expected a real, got {other:?}"),
1403 }
1404 }
1405
1406 #[test]
1407 fn depth_guard_caps_container_nesting_at_128() {
1408 assert!(from_value::<Value>(nested_arrays(128)).is_ok());
1409 assert!(matches!(
1410 from_value::<Value>(nested_arrays(129)),
1411 Err(Error::MaxDepthExceeded)
1412 ));
1413 let mut leafy = Value::from(vec![Value::from(1u8)]);
1415 for _ in 1..128 {
1416 leafy = Value::from(vec![leafy]);
1417 }
1418 assert!(from_value::<Value>(leafy).is_ok());
1419 assert!(matches!(
1421 from_value::<Value>(nested_arrays(2000)),
1422 Err(Error::MaxDepthExceeded)
1423 ));
1424 }
1425
1426 #[test]
1427 fn lax_decodes_the_lax_fixture() {
1428 #[derive(Deserialize, PartialEq, Debug)]
1431 #[serde(rename_all = "UPPERCASE")]
1432 struct LaxTestData {
1433 i64: i64,
1434 u64: u64,
1435 f64: f64,
1436 b: bool,
1437 d: Date,
1438 }
1439
1440 let value = dict([
1441 ("B", Value::from("1")),
1442 ("D", Value::from("2013-11-27 00:34:00 +0000")),
1443 ("F64", Value::from("3.0")),
1444 ("I64", Value::from("1")),
1445 ("U64", Value::from("2")),
1446 ]);
1447 assert_eq!(
1448 lax::<LaxTestData>(value).unwrap(),
1449 LaxTestData {
1450 i64: 1,
1451 u64: 2,
1452 f64: 3.0,
1453 b: true,
1454 d: rfc("2013-11-27T00:34:00Z"),
1455 }
1456 );
1457 }
1458
1459 #[test]
1460 fn illegal_lax_decodes_error() {
1461 assert!(lax::<i64>(Value::from("abc")).is_err());
1463 assert!(lax::<u64>(Value::from("abc")).is_err());
1464 assert!(lax::<f64>(Value::from("def")).is_err());
1465 assert!(lax::<bool>(Value::from("ghi")).is_err());
1466 assert!(lax::<Vec<u8>>(Value::from("jkl")).is_err());
1467 }
1468
1469 #[test]
1470 fn lax_bool_accepts_exactly_the_twelve_parse_bool_tokens() {
1471 for token in ["1", "t", "T", "TRUE", "true", "True"] {
1472 assert!(lax::<bool>(Value::from(token)).unwrap(), "{token}");
1473 }
1474 for token in ["0", "f", "F", "FALSE", "false", "False"] {
1475 assert!(!lax::<bool>(Value::from(token)).unwrap(), "{token}");
1476 }
1477 for token in ["yes", "2", "TrUe", ""] {
1478 assert!(lax::<bool>(Value::from(token)).is_err(), "{token}");
1479 }
1480 }
1481
1482 #[test]
1483 fn lax_integers_follow_sign_and_base_rules() {
1484 assert_eq!(lax::<i64>(Value::from("+5")).unwrap(), 5);
1485 assert_eq!(lax::<i64>(Value::from("-5")).unwrap(), -5);
1486 assert!(lax::<u64>(Value::from("+5")).is_err());
1487 assert!(lax::<u64>(Value::from("-5")).is_err());
1488 assert_eq!(lax::<u64>(Value::from("5")).unwrap(), 5);
1489 assert!(lax::<i64>(Value::from("0x10")).is_err());
1491 assert!(lax::<u64>(Value::from("0x10")).is_err());
1492 assert!(lax::<i64>(Value::from("5_0")).is_err());
1493 assert!(lax::<i8>(Value::from("300")).is_err());
1495 }
1496
1497 #[test]
1498 fn lax_floats_follow_c_style_parse() {
1499 assert!((lax::<f64>(Value::from("3.0")).unwrap() - 3.0).abs() < f64::EPSILON);
1500 assert!((lax::<f64>(Value::from("1e3")).unwrap() - 1000.0).abs() < f64::EPSILON);
1501 assert!(lax::<f64>(Value::from("-Inf")).unwrap().is_infinite());
1502 assert!(lax::<f64>(Value::from("nan")).unwrap().is_nan());
1503 assert!(lax::<f64>(Value::from("1e999")).is_err());
1504 assert!((lax::<f64>(Value::from("0x1p-2")).unwrap() - 0.25).abs() < f64::EPSILON);
1507 assert!((lax::<f64>(Value::from("1_000.5")).unwrap() - 1000.5).abs() < f64::EPSILON);
1508 }
1509
1510 #[test]
1511 fn lax_dates_use_the_text_layout_only() {
1512 assert_eq!(
1513 lax::<Date>(Value::from("2013-11-27 00:34:00 +0000")).unwrap(),
1514 rfc("2013-11-27T00:34:00Z")
1515 );
1516 assert_eq!(
1518 lax::<Date>(Value::from("2013-11-27 00:34:00 -0500")).unwrap(),
1519 rfc("2013-11-27T05:34:00Z")
1520 );
1521 assert!(matches!(
1522 lax::<Date>(Value::from("2013-11-27T00:34:00Z")),
1523 Err(Error::ParseScalar(_))
1524 ));
1525 assert!(lax::<Date>(Value::from("not a date")).is_err());
1526 }
1527
1528 #[test]
1529 fn lax_never_applies_inside_deserialize_any() {
1530 assert_eq!(lax::<Value>(Value::from("1")).unwrap(), Value::from("1"));
1531 let map = lax::<BTreeMap<String, Value>>(dict([("B", Value::from("1"))])).unwrap();
1532 assert_eq!(map.get("B"), Some(&Value::from("1")));
1533 }
1534
1535 #[test]
1536 fn public_from_value_is_always_strict() {
1537 assert!(from_value::<bool>(Value::from("1")).is_err());
1538 assert!(from_value::<i64>(Value::from("1")).is_err());
1539 assert!(from_value::<Date>(Value::from("2013-11-27 00:34:00 +0000")).is_err());
1540 }
1541
1542 #[test]
1543 fn enums_round_trip_their_external_tagging() {
1544 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1545 enum Repr {
1546 Unit,
1547 New(u8),
1548 Tuple(u8, u8),
1549 Struct { f: bool },
1550 }
1551
1552 for variant in [
1553 Repr::Unit,
1554 Repr::New(1),
1555 Repr::Tuple(1, 2),
1556 Repr::Struct { f: true },
1557 ] {
1558 let value = to_value(&variant).unwrap();
1559 assert_eq!(from_value::<Repr>(value).unwrap(), variant);
1560 }
1561
1562 assert_eq!(from_value::<Repr>(Value::from("Unit")).unwrap(), Repr::Unit);
1563 assert_eq!(
1564 from_value::<Repr>(dict([("New", Value::from(1u8))])).unwrap(),
1565 Repr::New(1)
1566 );
1567
1568 assert!(matches!(
1570 from_value::<Repr>(dict([
1571 ("New", Value::from(1u8)),
1572 ("Unit", Value::from(2u8)),
1573 ])),
1574 Err(Error::Message(_))
1575 ));
1576 assert!(from_value::<Repr>(dict([])).is_err());
1577 assert!(from_value::<Repr>(Value::from("New")).is_err());
1578 assert!(from_value::<Repr>(dict([("Unit", Value::from(1u8))])).is_err());
1579 assert!(from_value::<Repr>(Value::from("Bogus")).is_err());
1580 assert!(from_value::<Repr>(Value::from(1u8)).is_err());
1581 }
1582
1583 #[test]
1584 fn map_key_targets_must_be_string_shaped() {
1585 #[derive(Deserialize, PartialEq, Eq, PartialOrd, Ord, Debug)]
1586 struct SortaString(String);
1587
1588 let value = dict([("1", Value::from("first")), ("2", Value::from("second"))]);
1589 assert!(from_value::<BTreeMap<u32, String>>(value.clone()).is_err());
1590 assert!(lax::<BTreeMap<u32, String>>(value.clone()).is_err());
1592
1593 let aliased = from_value::<BTreeMap<SortaString, String>>(value).unwrap();
1594 assert_eq!(
1595 aliased.get(&SortaString("1".to_owned())),
1596 Some(&"first".to_owned())
1597 );
1598 }
1599
1600 #[test]
1601 fn fixed_arity_targets_reject_leftover_elements() {
1602 let three = Value::from(vec![Value::from(1u8), Value::from(2u8), Value::from(3u8)]);
1603 assert!(from_value::<(u8, u8)>(three.clone()).is_err());
1604 assert_eq!(from_value::<(u8, u8, u8)>(three).unwrap(), (1, 2, 3));
1605 assert!(from_value::<(u8, u8)>(Value::from(vec![Value::from(1u8)])).is_err());
1606 }
1607
1608 #[test]
1609 fn chars_demand_one_character_strings() {
1610 assert_eq!(from_value::<char>(Value::from("a")).unwrap(), 'a');
1611 assert_eq!(from_value::<char>(to_value(&'£').unwrap()).unwrap(), '£');
1612 assert!(from_value::<char>(Value::from("ab")).is_err());
1613 assert!(from_value::<char>(Value::from("")).is_err());
1614 assert!(from_value::<char>(Value::from(65u8)).is_err());
1615 }
1616
1617 #[test]
1618 fn borrowing_targets_fail_with_an_owned_tree() {
1619 let result = <&str>::deserialize(ValueDeserializer::new(Value::from("x"), false));
1620 assert!(result.is_err());
1621 }
1622
1623 #[test]
1624 fn options_wrap_present_values() {
1625 assert_eq!(
1626 from_value::<Option<i64>>(Value::from(5i64)).unwrap(),
1627 Some(5)
1628 );
1629 assert_eq!(
1630 from_value::<Option<Vec<u8>>>(Value::Data(vec![1])).unwrap(),
1631 Some(vec![1])
1632 );
1633 }
1634
1635 #[test]
1636 fn unit_targets_always_mismatch() {
1637 #[derive(Deserialize, Debug)]
1638 struct UnitStruct;
1639 #[derive(Deserialize, Debug)]
1641 struct Empty {}
1642
1643 assert!(from_value::<()>(dict([])).is_err());
1644 assert!(from_value::<UnitStruct>(dict([])).is_err());
1645 assert!(from_value::<Empty>(dict([("x", Value::from(1u8))])).is_ok());
1646 assert!(from_value::<Empty>(Value::from(1u8)).is_err());
1647 }
1648
1649 #[test]
1650 fn special_types_round_trip_inside_derived_structs() {
1651 #[derive(Serialize, Deserialize, PartialEq, Debug)]
1652 struct Archive {
1653 stamp: Date,
1654 reference: Uid,
1655 }
1656
1657 let archive = Archive {
1658 stamp: rfc("2013-11-27T00:34:00.25Z"),
1659 reference: Uid::from(42),
1660 };
1661 let value = to_value(&archive).unwrap();
1662 assert_eq!(
1663 value,
1664 dict([
1665 ("reference", Value::Uid(Uid::from(42))),
1666 ("stamp", Value::Date(rfc("2013-11-27T00:34:00.25Z"))),
1667 ])
1668 );
1669 assert_eq!(from_value::<Archive>(value).unwrap(), archive);
1670 }
1671
1672 #[test]
1673 fn integer_and_real_deserialize_from_their_values() {
1674 assert_eq!(
1675 from_value::<Integer>(Value::from(-1i64)).unwrap(),
1676 Integer::Signed(-1)
1677 );
1678 assert_eq!(
1679 from_value::<Integer>(Value::from(u64::MAX)).unwrap(),
1680 Integer::Unsigned(u64::MAX)
1681 );
1682 assert!(from_value::<Integer>(Value::from(1.5)).is_err());
1683
1684 let narrow = from_value::<Real>(Value::Real(Real::from(1.5f32))).unwrap();
1685 assert!(!narrow.wide());
1686 let wide = from_value::<Real>(Value::from(1.5)).unwrap();
1687 assert!(wide.wide());
1688 assert!(from_value::<Real>(Value::from(1u8)).is_err());
1689 }
1690}