1use crate::error::{Error, Result};
7use crate::prelude::f64_fract;
8use crate::prelude::*;
9use crate::span_context;
10use crate::value::{Number, Value};
11
12#[derive(Debug, Clone, Copy)]
24pub struct Deserializer<'de> {
25 pub(crate) value: &'de Value,
26 pub(crate) span_ctx: Option<&'de span_context::SpanContext>,
27 pub(crate) ignore_binary_tag_for_string: bool,
33 pub(crate) plain_scalar_strings: bool,
40}
41
42impl<'de> Deserializer<'de> {
43 #[must_use]
53 pub fn new(value: &'de Value) -> Self {
54 Deserializer {
55 value,
56 span_ctx: None,
57 ignore_binary_tag_for_string: false,
58 plain_scalar_strings: false,
59 }
60 }
61
62 #[must_use]
79 pub fn with_span_context(value: &'de Value, span_ctx: &'de span_context::SpanContext) -> Self {
80 Deserializer {
81 value,
82 span_ctx: Some(span_ctx),
83 ignore_binary_tag_for_string: false,
84 plain_scalar_strings: false,
85 }
86 }
87
88 pub(crate) fn with_options(
94 value: &'de Value,
95 span_ctx: Option<&'de span_context::SpanContext>,
96 ignore_binary_tag_for_string: bool,
97 plain_scalar_strings: bool,
98 ) -> Self {
99 Deserializer {
100 value,
101 span_ctx,
102 ignore_binary_tag_for_string,
103 plain_scalar_strings,
104 }
105 }
106
107 pub(crate) fn descend(&self, value: &'de Value) -> Self {
112 Deserializer {
113 value,
114 span_ctx: self.span_ctx,
115 ignore_binary_tag_for_string: self.ignore_binary_tag_for_string,
116 plain_scalar_strings: self.plain_scalar_strings,
117 }
118 }
119
120 fn wrap_err<T>(&self, res: Result<T>) -> Result<T> {
142 let err = match res {
143 Ok(value) => return Ok(value),
144 Err(err) => err,
145 };
146 let Some(ctx) = self.span_ctx else {
147 return Err(err);
148 };
149 let ptr: *const Value = self.value;
150 let addr = ptr as usize;
151 let Some(span) = ctx.spans.get(&addr) else {
152 return Err(err);
153 };
154 let message = match err {
155 Error::Deserialize(msg) | Error::Custom(msg) => msg,
156 worded @ (Error::TypeMismatch { .. }
157 | Error::UnknownField(_)
158 | Error::MissingField(_)) => worded.to_string(),
159 other => return Err(other),
160 };
161 #[cfg(feature = "std")]
166 span_context::record_error_node(addr);
167 Err(Error::deserialize_at(message, &ctx.source, span.0))
168 }
169}
170
171impl<'de> serde_core::Deserializer<'de> for Deserializer<'de> {
172 type Error = Error;
173
174 fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
175 where
176 V: serde_core::de::Visitor<'de>,
177 {
178 match self.value {
179 Value::Null => self.wrap_err(visitor.visit_none()),
180 Value::Bool(b) => self.wrap_err(visitor.visit_bool(*b)),
181 Value::Number(Number::Integer(n)) => self.wrap_err(visitor.visit_i64(*n)),
182 #[cfg(feature = "lossless-u64")]
183 Value::Number(Number::Unsigned(n)) => self.wrap_err(visitor.visit_u64(*n)),
184 Value::Number(Number::Float(n)) => self.wrap_err(visitor.visit_f64(*n)),
185 Value::String(s) => self.wrap_err(visitor.visit_str(s)),
186 Value::Sequence(_) => self.deserialize_seq(visitor),
187 Value::Mapping(_) => self.deserialize_map(visitor),
188 Value::Tagged(tagged) => {
189 self.wrap_err(visitor.visit_enum(EnumAccess {
210 variant: tagged.tag().as_str(),
211 value: tagged.value(),
212 span_ctx: self.span_ctx,
213 }))
214 }
215 }
216 }
217
218 fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
219 where
220 V: serde_core::de::Visitor<'de>,
221 {
222 match self.value {
223 Value::Bool(b) => self.wrap_err(visitor.visit_bool(*b)),
224 _ => self.wrap_err(Err(Error::TypeMismatch {
225 expected: "bool",
226 found: type_name(self.value),
227 })),
228 }
229 }
230
231 fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
232 where
233 V: serde_core::de::Visitor<'de>,
234 {
235 self.deserialize_i64(visitor)
236 }
237
238 fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
239 where
240 V: serde_core::de::Visitor<'de>,
241 {
242 self.deserialize_i64(visitor)
243 }
244
245 fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
246 where
247 V: serde_core::de::Visitor<'de>,
248 {
249 self.deserialize_i64(visitor)
250 }
251
252 fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
253 where
254 V: serde_core::de::Visitor<'de>,
255 {
256 match self.value {
257 Value::Number(Number::Integer(n)) => self.wrap_err(visitor.visit_i64(*n)),
258 #[cfg(feature = "lossless-u64")]
259 Value::Number(Number::Unsigned(n)) => match i64::try_from(*n) {
260 Ok(n) => self.wrap_err(visitor.visit_i64(n)),
261 Err(_) => self.wrap_err(Err(Error::TypeMismatch {
267 expected: "signed integer (i64)",
268 found: format!("unsigned integer {n}, above i64::MAX"),
269 })),
270 },
271 Value::Number(Number::Float(n))
272 if f64_fract(*n) == 0.0
273 && *n >= i64::MIN as f64
274 && *n <= i64::MAX as f64
275 && !n.is_nan() =>
276 {
277 self.wrap_err(visitor.visit_i64(*n as i64))
278 }
279 _ => self.wrap_err(Err(Error::TypeMismatch {
280 expected: "integer",
281 found: type_name(self.value),
282 })),
283 }
284 }
285
286 fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
287 where
288 V: serde_core::de::Visitor<'de>,
289 {
290 self.deserialize_u64(visitor)
291 }
292
293 fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
294 where
295 V: serde_core::de::Visitor<'de>,
296 {
297 self.deserialize_u64(visitor)
298 }
299
300 fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
301 where
302 V: serde_core::de::Visitor<'de>,
303 {
304 self.deserialize_u64(visitor)
305 }
306
307 fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
308 where
309 V: serde_core::de::Visitor<'de>,
310 {
311 match self.value {
312 Value::Number(Number::Integer(n)) if *n >= 0 => {
313 self.wrap_err(visitor.visit_u64(*n as u64))
314 }
315 Value::Number(Number::Integer(n)) => self.wrap_err(Err(Error::TypeMismatch {
320 expected: "unsigned integer",
321 found: format!("negative integer {n}"),
322 })),
323 #[cfg(feature = "lossless-u64")]
324 Value::Number(Number::Unsigned(n)) => self.wrap_err(visitor.visit_u64(*n)),
325 Value::Number(Number::Float(n))
326 if f64_fract(*n) == 0.0 && *n >= 0.0 && *n <= u64::MAX as f64 && !n.is_nan() =>
327 {
328 self.wrap_err(visitor.visit_u64(*n as u64))
329 }
330 _ => self.wrap_err(Err(Error::TypeMismatch {
331 expected: "unsigned integer",
332 found: type_name(self.value),
333 })),
334 }
335 }
336
337 fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
338 where
339 V: serde_core::de::Visitor<'de>,
340 {
341 self.deserialize_f64(visitor)
342 }
343
344 fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
345 where
346 V: serde_core::de::Visitor<'de>,
347 {
348 match self.value {
349 Value::Number(Number::Float(n)) => self.wrap_err(visitor.visit_f64(*n)),
350 Value::Number(Number::Integer(n)) => self.wrap_err(visitor.visit_f64(*n as f64)),
351 #[cfg(feature = "lossless-u64")]
352 Value::Number(Number::Unsigned(n)) => self.wrap_err(visitor.visit_f64(*n as f64)),
353 _ => self.wrap_err(Err(Error::TypeMismatch {
354 expected: "float",
355 found: type_name(self.value),
356 })),
357 }
358 }
359
360 fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
361 where
362 V: serde_core::de::Visitor<'de>,
363 {
364 match self.value {
365 Value::String(s) if s.chars().count() == 1 => {
366 self.wrap_err(visitor.visit_char(s.chars().next().unwrap()))
367 }
368 _ if self.plain_scalar_strings => match scalar_as_text(self.value) {
374 Some(text) if text.chars().count() == 1 => {
375 self.wrap_err(visitor.visit_char(text.chars().next().unwrap()))
376 }
377 _ => self.wrap_err(Err(Error::TypeMismatch {
378 expected: "char",
379 found: type_name(self.value),
380 })),
381 },
382 _ => self.wrap_err(Err(Error::TypeMismatch {
383 expected: "char",
384 found: type_name(self.value),
385 })),
386 }
387 }
388
389 fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
390 where
391 V: serde_core::de::Visitor<'de>,
392 {
393 match self.value {
394 Value::String(s) => self.wrap_err(visitor.visit_str(s)),
395 Value::Tagged(boxed)
403 if self.ignore_binary_tag_for_string && is_binary_tag(boxed.tag().as_str()) =>
404 {
405 match boxed.value() {
406 Value::String(s) => self.wrap_err(visitor.visit_str(s)),
407 other => self.wrap_err(Err(Error::TypeMismatch {
408 expected: "string-shaped !!binary content",
409 found: type_name(other),
410 })),
411 }
412 }
413 _ if self.plain_scalar_strings => match scalar_as_text(self.value) {
421 Some(text) => self.wrap_err(visitor.visit_str(&text)),
422 None => self.wrap_err(Err(Error::TypeMismatch {
423 expected: "string",
424 found: type_name(self.value),
425 })),
426 },
427 _ => self.wrap_err(Err(Error::TypeMismatch {
428 expected: "string",
429 found: type_name(self.value),
430 })),
431 }
432 }
433
434 fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
435 where
436 V: serde_core::de::Visitor<'de>,
437 {
438 self.deserialize_str(visitor)
439 }
440
441 fn deserialize_bytes<V>(self, visitor: V) -> Result<V::Value>
442 where
443 V: serde_core::de::Visitor<'de>,
444 {
445 match self.value {
446 Value::String(s) => self.wrap_err(visitor.visit_bytes(s.as_bytes())),
447 Value::Tagged(boxed) if is_binary_tag(boxed.tag().as_str()) => match boxed.value() {
452 Value::String(s) => match crate::base64::decode(s) {
453 Ok(bytes) => self.wrap_err(visitor.visit_byte_buf(bytes)),
454 Err(why) => self.wrap_err(Err(Error::Deserialize(format!("!!binary: {why}")))),
455 },
456 other => self.wrap_err(Err(Error::TypeMismatch {
457 expected: "string-shaped !!binary content",
458 found: type_name(other),
459 })),
460 },
461 _ => self.wrap_err(Err(Error::TypeMismatch {
462 expected: "bytes",
463 found: type_name(self.value),
464 })),
465 }
466 }
467
468 fn deserialize_byte_buf<V>(self, visitor: V) -> Result<V::Value>
469 where
470 V: serde_core::de::Visitor<'de>,
471 {
472 self.deserialize_bytes(visitor)
473 }
474
475 fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
476 where
477 V: serde_core::de::Visitor<'de>,
478 {
479 match self.value {
480 Value::Null => self.wrap_err(visitor.visit_none()),
481 _ => self.wrap_err(visitor.visit_some(self)),
482 }
483 }
484
485 fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
486 where
487 V: serde_core::de::Visitor<'de>,
488 {
489 match self.value {
490 Value::Null => self.wrap_err(visitor.visit_unit()),
491 _ => self.wrap_err(Err(Error::TypeMismatch {
492 expected: "null",
493 found: type_name(self.value),
494 })),
495 }
496 }
497
498 fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
499 where
500 V: serde_core::de::Visitor<'de>,
501 {
502 self.deserialize_unit(visitor)
503 }
504
505 fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value>
506 where
507 V: serde_core::de::Visitor<'de>,
508 {
509 if name == crate::spanned::SPANNED_TYPE_NAME {
510 return visitor.visit_map(SpannedMapAccess::new(
511 self.value,
512 self.span_ctx,
513 self.ignore_binary_tag_for_string,
514 self.plain_scalar_strings,
515 ));
516 }
517 self.wrap_err(visitor.visit_newtype_struct(self))
518 }
519
520 fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
521 where
522 V: serde_core::de::Visitor<'de>,
523 {
524 match self.value {
525 Value::Sequence(seq) => {
526 self.wrap_err(visitor.visit_seq(ValueSeqAccess::from_de(&self, seq)))
527 }
528 Value::Tagged(tagged) => self.descend(tagged.value()).deserialize_seq(visitor),
533 _ => self.wrap_err(Err(Error::TypeMismatch {
534 expected: "sequence",
535 found: type_name(self.value),
536 })),
537 }
538 }
539
540 fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
541 where
542 V: serde_core::de::Visitor<'de>,
543 {
544 self.deserialize_seq(visitor)
545 }
546
547 fn deserialize_tuple_struct<V>(
548 self,
549 _name: &'static str,
550 _len: usize,
551 visitor: V,
552 ) -> Result<V::Value>
553 where
554 V: serde_core::de::Visitor<'de>,
555 {
556 self.deserialize_seq(visitor)
557 }
558
559 fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
560 where
561 V: serde_core::de::Visitor<'de>,
562 {
563 match self.value {
564 Value::Mapping(map) => {
565 self.wrap_err(visitor.visit_map(ValueMapAccess::from_de(&self, map)))
566 }
567 Value::Null => self.wrap_err(visitor.visit_map(EmptyMapAccess)),
571 Value::Tagged(tagged) => self.descend(tagged.value()).deserialize_map(visitor),
577 _ => self.wrap_err(Err(Error::TypeMismatch {
578 expected: "mapping",
579 found: type_name(self.value),
580 })),
581 }
582 }
583
584 fn deserialize_struct<V>(
585 self,
586 name: &'static str,
587 _fields: &'static [&'static str],
588 visitor: V,
589 ) -> Result<V::Value>
590 where
591 V: serde_core::de::Visitor<'de>,
592 {
593 if name == crate::spanned::SPANNED_TYPE_NAME {
594 return visitor.visit_map(SpannedMapAccess::new(
595 self.value,
596 self.span_ctx,
597 self.ignore_binary_tag_for_string,
598 self.plain_scalar_strings,
599 ));
600 }
601 self.deserialize_map(visitor)
602 }
603
604 fn deserialize_enum<V>(
605 self,
606 _name: &'static str,
607 _variants: &'static [&'static str],
608 visitor: V,
609 ) -> Result<V::Value>
610 where
611 V: serde_core::de::Visitor<'de>,
612 {
613 match self.value {
614 Value::String(variant) => {
615 let de =
616 serde_core::de::value::StrDeserializer::<'de, Error>::new(variant.as_str());
617 self.wrap_err(visitor.visit_enum(de))
618 }
619 Value::Mapping(map) if map.len() == 1 => {
620 let (variant, value) = map.iter().next().unwrap();
621 self.wrap_err(visitor.visit_enum(EnumAccess {
622 variant,
623 value,
624 span_ctx: self.span_ctx,
625 }))
626 }
627 _ => self.wrap_err(Err(Error::TypeMismatch {
628 expected: "string or single-key mapping",
629 found: type_name(self.value),
630 })),
631 }
632 }
633
634 fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
635 where
636 V: serde_core::de::Visitor<'de>,
637 {
638 match self.value {
639 Value::String(s) => self.wrap_err(visitor.visit_str(s)),
640 _ => self.deserialize_any(visitor),
641 }
642 }
643
644 fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
645 where
646 V: serde_core::de::Visitor<'de>,
647 {
648 self.wrap_err(visitor.visit_unit())
649 }
650}
651
652pub(crate) struct ValueSeqAccess<'de> {
653 iter: core::slice::Iter<'de, Value>,
654 span_ctx: Option<&'de span_context::SpanContext>,
655 ignore_binary_tag_for_string: bool,
656 plain_scalar_strings: bool,
657}
658
659impl<'de> ValueSeqAccess<'de> {
660 pub(crate) fn from_de(de: &Deserializer<'de>, seq: &'de [Value]) -> Self {
661 ValueSeqAccess {
662 iter: seq.iter(),
663 span_ctx: de.span_ctx,
664 ignore_binary_tag_for_string: de.ignore_binary_tag_for_string,
665 plain_scalar_strings: de.plain_scalar_strings,
666 }
667 }
668}
669
670impl<'de> serde_core::de::SeqAccess<'de> for ValueSeqAccess<'de> {
671 type Error = Error;
672
673 fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
674 where
675 T: serde_core::de::DeserializeSeed<'de>,
676 {
677 match self.iter.next() {
678 Some(value) => {
679 let de = Deserializer {
680 value,
681 span_ctx: self.span_ctx,
682 ignore_binary_tag_for_string: self.ignore_binary_tag_for_string,
683 plain_scalar_strings: self.plain_scalar_strings,
684 };
685 seed.deserialize(de).map(Some)
686 }
687 None => Ok(None),
688 }
689 }
690}
691
692pub(crate) struct ValueMapAccess<'de> {
693 iter: indexmap::map::Iter<'de, String, Value>,
694 value: Option<&'de Value>,
695 span_ctx: Option<&'de span_context::SpanContext>,
696 ignore_binary_tag_for_string: bool,
697 plain_scalar_strings: bool,
698}
699
700impl<'de> ValueMapAccess<'de> {
701 pub(crate) fn from_de(de: &Deserializer<'de>, map: &'de crate::value::Mapping) -> Self {
702 ValueMapAccess {
703 iter: map.iter(),
704 value: None,
705 span_ctx: de.span_ctx,
706 ignore_binary_tag_for_string: de.ignore_binary_tag_for_string,
707 plain_scalar_strings: de.plain_scalar_strings,
708 }
709 }
710
711 fn child_de(&self, value: &'de Value) -> Deserializer<'de> {
714 Deserializer {
715 value,
716 span_ctx: self.span_ctx,
717 ignore_binary_tag_for_string: self.ignore_binary_tag_for_string,
718 plain_scalar_strings: self.plain_scalar_strings,
719 }
720 }
721}
722
723impl<'de> serde_core::de::MapAccess<'de> for ValueMapAccess<'de> {
724 type Error = Error;
725
726 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
727 where
728 K: serde_core::de::DeserializeSeed<'de>,
729 {
730 match self.iter.next() {
731 Some((key, value)) => {
732 self.value = Some(value);
733 let de = self.child_de(value);
734 let text = self
737 .span_ctx
738 .and_then(|ctx| ctx.key_text(key))
739 .unwrap_or(key.as_str());
740 let key_de = serde_core::de::value::StrDeserializer::<'de, Error>::new(text);
741 de.wrap_err(seed.deserialize(key_de).map(Some))
742 }
743 None => Ok(None),
744 }
745 }
746
747 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
748 where
749 V: serde_core::de::DeserializeSeed<'de>,
750 {
751 match self.value.take() {
752 Some(value) => {
753 let de = self.child_de(value);
754 let res = seed.deserialize(de);
755 de.wrap_err(res)
756 }
757 None => Err(serde_core::de::Error::custom("value is missing")),
758 }
759 }
760}
761
762pub(crate) struct EmptyMapAccess;
772
773impl<'de> serde_core::de::MapAccess<'de> for EmptyMapAccess {
774 type Error = Error;
775
776 fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>>
777 where
778 K: serde_core::de::DeserializeSeed<'de>,
779 {
780 Ok(None)
781 }
782
783 fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value>
784 where
785 V: serde_core::de::DeserializeSeed<'de>,
786 {
787 Err(serde_core::de::Error::custom("value is missing"))
788 }
789}
790
791struct EnumAccess<'de> {
792 variant: &'de str,
793 value: &'de Value,
794 span_ctx: Option<&'de span_context::SpanContext>,
795}
796
797impl<'de> serde_core::de::EnumAccess<'de> for EnumAccess<'de> {
798 type Error = Error;
799 type Variant = VariantAccess<'de>;
800
801 fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
802 where
803 V: serde_core::de::DeserializeSeed<'de>,
804 {
805 let de = serde_core::de::value::StrDeserializer::<'de, Error>::new(self.variant);
806 let variant = seed.deserialize(de)?;
807 let visitor = VariantAccess {
808 value: self.value,
809 span_ctx: self.span_ctx,
810 };
811 Ok((variant, visitor))
812 }
813}
814
815struct VariantAccess<'de> {
816 value: &'de Value,
817 span_ctx: Option<&'de span_context::SpanContext>,
818}
819
820impl<'de> serde_core::de::VariantAccess<'de> for VariantAccess<'de> {
821 type Error = Error;
822
823 fn unit_variant(self) -> Result<()> {
824 let de = if let Some(ctx) = self.span_ctx {
825 Deserializer::with_span_context(self.value, ctx)
826 } else {
827 Deserializer::new(self.value)
828 };
829 serde_core::Deserialize::deserialize(de)
830 }
831
832 fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
833 where
834 T: serde_core::de::DeserializeSeed<'de>,
835 {
836 let de = if let Some(ctx) = self.span_ctx {
837 Deserializer::with_span_context(self.value, ctx)
838 } else {
839 Deserializer::new(self.value)
840 };
841 seed.deserialize(de)
842 }
843
844 fn tuple_variant<V>(self, _len: usize, visitor: V) -> Result<V::Value>
845 where
846 V: serde_core::de::Visitor<'de>,
847 {
848 let de = if let Some(ctx) = self.span_ctx {
849 Deserializer::with_span_context(self.value, ctx)
850 } else {
851 Deserializer::new(self.value)
852 };
853 serde_core::Deserializer::deserialize_seq(de, visitor)
854 }
855
856 fn struct_variant<V>(self, _fields: &'static [&'static str], visitor: V) -> Result<V::Value>
857 where
858 V: serde_core::de::Visitor<'de>,
859 {
860 let de = if let Some(ctx) = self.span_ctx {
861 Deserializer::with_span_context(self.value, ctx)
862 } else {
863 Deserializer::new(self.value)
864 };
865 serde_core::Deserializer::deserialize_map(de, visitor)
866 }
867}
868
869pub(crate) struct SpannedMapAccess<'de> {
870 value: &'de Value,
871 span_ctx: Option<&'de span_context::SpanContext>,
872 ignore_binary_tag_for_string: bool,
878 plain_scalar_strings: bool,
879 fields: core::slice::Iter<'static, &'static str>,
880 locations: Option<(crate::error::Location, crate::error::Location)>,
883}
884
885impl<'de> SpannedMapAccess<'de> {
886 pub(crate) fn new(
887 value: &'de Value,
888 span_ctx: Option<&'de span_context::SpanContext>,
889 ignore_binary_tag_for_string: bool,
890 plain_scalar_strings: bool,
891 ) -> Self {
892 SpannedMapAccess {
893 value,
894 span_ctx,
895 ignore_binary_tag_for_string,
896 plain_scalar_strings,
897 fields: crate::spanned::SPANNED_FIELDS.iter(),
898 locations: None,
899 }
900 }
901
902 fn locations(&mut self) -> (crate::error::Location, crate::error::Location) {
904 let (value, span_ctx) = (self.value, self.span_ctx);
905 *self.locations.get_or_insert_with(|| {
906 let ptr: *const Value = value;
907 let addr = ptr as usize;
908 span_ctx
912 .and_then(|ctx| {
913 ctx.spans
914 .get(&addr)
915 .map(|&(start, end)| (ctx.location(start), ctx.location(end)))
916 })
917 .unwrap_or_default()
918 })
919 }
920}
921
922impl<'de> serde_core::de::MapAccess<'de> for SpannedMapAccess<'de> {
923 type Error = Error;
924
925 fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
926 where
927 K: serde_core::de::DeserializeSeed<'de>,
928 {
929 match self.fields.next() {
930 Some(field) => {
931 let de = serde_core::de::value::BorrowedStrDeserializer::<'_, Error>::new(field);
932 seed.deserialize(de).map(Some)
933 }
934 None => Ok(None),
935 }
936 }
937
938 fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
939 where
940 V: serde_core::de::DeserializeSeed<'de>,
941 {
942 use crate::spanned::{
943 SPANNED_FIELD_END_COLUMN, SPANNED_FIELD_END_INDEX, SPANNED_FIELD_END_LINE,
944 SPANNED_FIELD_START_COLUMN, SPANNED_FIELD_START_INDEX, SPANNED_FIELD_START_LINE,
945 SPANNED_FIELD_VALUE, SPANNED_FIELDS,
946 };
947 let last_field = SPANNED_FIELDS[SPANNED_FIELDS.len() - 1 - (self.fields.len())];
948
949 if last_field == SPANNED_FIELD_VALUE {
950 let de = Deserializer::with_options(
951 self.value,
952 self.span_ctx,
953 self.ignore_binary_tag_for_string,
954 self.plain_scalar_strings,
955 );
956 return de.wrap_err(seed.deserialize(de));
957 }
958
959 let (loc, end_loc) = self.locations();
960
961 let val = match last_field {
962 SPANNED_FIELD_START_LINE => loc.line(),
963 SPANNED_FIELD_START_COLUMN => loc.column(),
964 SPANNED_FIELD_START_INDEX => loc.index(),
965 SPANNED_FIELD_END_LINE => end_loc.line(),
966 SPANNED_FIELD_END_COLUMN => end_loc.column(),
967 SPANNED_FIELD_END_INDEX => end_loc.index(),
968 _ => crate::error::invariant_violated(
969 "spanned-field index outside the SPANNED_FIELDS array",
970 ),
971 };
972
973 seed.deserialize(serde_core::de::IntoDeserializer::into_deserializer(val))
974 }
975}
976
977pub(crate) fn is_binary_tag(tag: &str) -> bool {
984 matches!(
985 tag,
986 "!!binary" | "binary" | "tag:yaml.org,2002:binary" | "!<tag:yaml.org,2002:binary>"
987 )
988}
989
990fn type_name(value: &Value) -> String {
991 match value {
992 Value::Null => "null".to_owned(),
993 Value::Bool(_) => "bool".to_owned(),
994 Value::Number(Number::Integer(_)) => "integer".to_owned(),
995 #[cfg(feature = "lossless-u64")]
996 Value::Number(Number::Unsigned(_)) => "integer".to_owned(),
997 Value::Number(Number::Float(_)) => "float".to_owned(),
998 Value::String(_) => "string".to_owned(),
999 Value::Sequence(_) => "sequence".to_owned(),
1000 Value::Mapping(_) => "mapping".to_owned(),
1001 Value::Tagged(tagged) => format!("tagged value (!{})", tagged.tag().as_str()),
1002 }
1003}
1004
1005fn scalar_as_text(value: &Value) -> Option<Cow<'_, str>> {
1028 match value {
1029 Value::Bool(b) => Some(Cow::Borrowed(if *b { "true" } else { "false" })),
1030 Value::Null => Some(Cow::Borrowed("")),
1031 Value::Number(Number::Integer(n)) => Some(Cow::Owned(n.to_string())),
1032 #[cfg(feature = "lossless-u64")]
1033 Value::Number(Number::Unsigned(n)) => Some(Cow::Owned(n.to_string())),
1034 Value::Number(Number::Float(n)) => Some(Cow::Owned(format_float_for_string(*n))),
1035 _ => None,
1036 }
1037}
1038
1039fn format_float_for_string(n: f64) -> String {
1046 if n.is_nan() {
1047 return ".nan".to_owned();
1048 }
1049 if n.is_infinite() {
1050 return if n > 0.0 {
1051 ".inf".to_owned()
1052 } else {
1053 "-.inf".to_owned()
1054 };
1055 }
1056 #[cfg(feature = "fast-float")]
1057 {
1058 ryu::Buffer::new().format(n).to_owned()
1059 }
1060 #[cfg(not(feature = "fast-float"))]
1061 {
1062 format!("{n:?}")
1063 }
1064}