Skip to main content

yaml_rt_serde/
de.rs

1use std::{borrow::Cow, cell::Cell, io::Read, rc::Rc, str};
2
3use serde::Deserializer as _;
4use serde::de::{
5    self, DeserializeOwned, DeserializeSeed, EnumAccess, MapAccess, SeqAccess, VariantAccess,
6    Visitor,
7};
8use yaml_rt_core::{
9    NodeId, NonFiniteFloat, ResolvedScalar, SemanticKind, Span, YamlDoc, YamlScalarStyle,
10    resolve_scalar,
11};
12
13use crate::{Error, Result};
14
15const MAX_DEPTH: u8 = 128;
16
17struct Input<'de> {
18    doc: Option<YamlDoc>,
19    borrowed: Option<&'de str>,
20    error: Option<Error>,
21    semantic_len: usize,
22}
23
24impl<'de> Input<'de> {
25    fn parsed(text: String, borrowed: Option<&'de str>) -> Self {
26        match YamlDoc::parse_owned(text) {
27            Ok(doc) => {
28                let semantic_len = doc.events().count().max(1);
29                Self {
30                    doc: Some(doc),
31                    borrowed,
32                    error: None,
33                    semantic_len,
34                }
35            }
36            Err(error) => Self {
37                doc: None,
38                borrowed,
39                error: Some(error.into()),
40                semantic_len: 1,
41            },
42        }
43    }
44
45    fn failed(error: Error) -> Self {
46        Self {
47            doc: None,
48            borrowed: None,
49            error: Some(error),
50            semantic_len: 1,
51        }
52    }
53}
54
55/// A Serde deserializer over one YAML stream.
56pub struct Deserializer<'de> {
57    input: Rc<Input<'de>>,
58    selected: Option<usize>,
59    next_index: usize,
60    yielded_error: bool,
61}
62
63impl<'de> Deserializer<'de> {
64    /// Creates a deserializer borrowing a UTF-8 YAML string.
65    #[must_use]
66    #[allow(clippy::should_implement_trait)]
67    pub fn from_str(input: &'de str) -> Self {
68        Self::new(Input::parsed(input.to_owned(), Some(input)))
69    }
70
71    /// Creates a deserializer borrowing a UTF-8 YAML byte slice.
72    #[must_use]
73    pub fn from_slice(input: &'de [u8]) -> Self {
74        match str::from_utf8(input) {
75            Ok(input) => Self::from_str(input),
76            Err(error) => Self::new(Input::failed(Error::message(error.to_string()))),
77        }
78    }
79
80    fn new(input: Input<'de>) -> Self {
81        Self {
82            input: Rc::new(input),
83            selected: None,
84            next_index: 0,
85            yielded_error: false,
86        }
87    }
88
89    fn node_deserializer(&self) -> Result<NodeDeserializer<'_, 'de>> {
90        if let Some(error) = &self.input.error {
91            return Err(error.clone());
92        }
93        let doc = self
94            .input
95            .doc
96            .as_ref()
97            .expect("parsed input has a document");
98        let index = if let Some(index) = self.selected {
99            index
100        } else {
101            match doc.document_count() {
102                0 => return Err(Error::message("EOF while parsing a value")),
103                1 => 0,
104                _ => {
105                    return Err(Error::message(
106                        "deserializing from YAML containing more than one document is not supported",
107                    ));
108                }
109            }
110        };
111        let node = doc.document_root(index).map_err(Error::from)?;
112        Ok(NodeDeserializer {
113            input: &self.input,
114            node,
115            path: ".".to_owned(),
116            depth: MAX_DEPTH,
117            alias_jumps: Rc::new(Cell::new(0)),
118            ignore_tag: false,
119        })
120    }
121}
122
123impl Deserializer<'static> {
124    /// Creates a deserializer by reading an owned UTF-8 YAML stream.
125    #[must_use]
126    pub fn from_reader<R>(mut reader: R) -> Self
127    where
128        R: Read,
129    {
130        let mut input = String::new();
131        match reader.read_to_string(&mut input) {
132            Ok(_) => Self::new(Input::parsed(input, None)),
133            Err(error) => Self::new(Input::failed(Error::io(error))),
134        }
135    }
136}
137
138impl<'de> Iterator for Deserializer<'de> {
139    type Item = Self;
140
141    fn next(&mut self) -> Option<Self::Item> {
142        if self.input.error.is_some() {
143            if self.yielded_error {
144                return None;
145            }
146            self.yielded_error = true;
147            return Some(Self {
148                input: Rc::clone(&self.input),
149                selected: Some(0),
150                next_index: 0,
151                yielded_error: true,
152            });
153        }
154        let count = self.input.doc.as_ref()?.document_count();
155        if self.next_index >= count {
156            return None;
157        }
158        let selected = self.next_index;
159        self.next_index += 1;
160        Some(Self {
161            input: Rc::clone(&self.input),
162            selected: Some(selected),
163            next_index: 0,
164            yielded_error: false,
165        })
166    }
167}
168
169/// Deserializes exactly one YAML document from a string.
170pub fn from_str<'de, T>(input: &'de str) -> Result<T>
171where
172    T: serde::Deserialize<'de>,
173{
174    T::deserialize(Deserializer::from_str(input))
175}
176
177/// Deserializes exactly one YAML document from a byte slice.
178pub fn from_slice<'de, T>(input: &'de [u8]) -> Result<T>
179where
180    T: serde::Deserialize<'de>,
181{
182    T::deserialize(Deserializer::from_slice(input))
183}
184
185/// Deserializes exactly one owned YAML document from a reader.
186pub fn from_reader<R, T>(reader: R) -> Result<T>
187where
188    R: Read,
189    T: DeserializeOwned,
190{
191    T::deserialize(Deserializer::from_reader(reader))
192}
193
194macro_rules! delegate_deserializer {
195    ($($method:ident $(($($arg:ident : $ty:ty),*))?;)+) => {
196        $(
197            fn $method<V>(self, $($($arg: $ty,)*)? visitor: V) -> Result<V::Value>
198            where
199                V: Visitor<'de>,
200            {
201                self.node_deserializer()?.$method($($($arg,)*)? visitor)
202            }
203        )+
204    };
205}
206
207impl<'de> de::Deserializer<'de> for Deserializer<'de> {
208    type Error = Error;
209
210    delegate_deserializer! {
211        deserialize_any;
212        deserialize_bool;
213        deserialize_i8;
214        deserialize_i16;
215        deserialize_i32;
216        deserialize_i64;
217        deserialize_i128;
218        deserialize_u8;
219        deserialize_u16;
220        deserialize_u32;
221        deserialize_u64;
222        deserialize_u128;
223        deserialize_f32;
224        deserialize_f64;
225        deserialize_char;
226        deserialize_str;
227        deserialize_string;
228        deserialize_bytes;
229        deserialize_byte_buf;
230        deserialize_option;
231        deserialize_unit;
232        deserialize_unit_struct(name: &'static str);
233        deserialize_newtype_struct(name: &'static str);
234        deserialize_seq;
235        deserialize_tuple(len: usize);
236        deserialize_tuple_struct(name: &'static str, len: usize);
237        deserialize_map;
238        deserialize_struct(name: &'static str, fields: &'static [&'static str]);
239        deserialize_enum(name: &'static str, variants: &'static [&'static str]);
240        deserialize_identifier;
241        deserialize_ignored_any;
242    }
243
244    fn is_human_readable(&self) -> bool {
245        true
246    }
247}
248
249#[derive(Clone)]
250struct NodeDeserializer<'input, 'de> {
251    input: &'input Input<'de>,
252    node: Option<NodeId>,
253    path: String,
254    depth: u8,
255    alias_jumps: Rc<Cell<usize>>,
256    ignore_tag: bool,
257}
258
259impl<'input, 'de> NodeDeserializer<'input, 'de> {
260    fn doc(&self) -> &'input YamlDoc {
261        self.input.doc.as_ref().expect("node input is parsed")
262    }
263
264    fn span(&self) -> Span {
265        self.node
266            .and_then(|node| self.doc().node(node).map(|node| node.span()))
267            .unwrap_or_else(|| Span::empty(0))
268    }
269
270    fn annotate<T>(&self, result: Result<T>) -> Result<T> {
271        result.map_err(|error| error.at(self.doc(), self.span()).with_path(&self.path))
272    }
273
274    fn descend(&self, node: Option<NodeId>, path: String) -> Result<Self> {
275        let depth = self
276            .depth
277            .checked_sub(1)
278            .ok_or_else(|| Error::message("recursion limit exceeded"));
279        let depth = self.annotate(depth)?;
280        Ok(Self {
281            input: self.input,
282            node,
283            path,
284            depth,
285            alias_jumps: Rc::clone(&self.alias_jumps),
286            ignore_tag: false,
287        })
288    }
289
290    fn resolved(mut self) -> Result<Self> {
291        let mut seen = Vec::new();
292        while let Some(node) = self.node {
293            if !matches!(self.doc().semantic_kind(node), Some(SemanticKind::Alias)) {
294                break;
295            }
296            if seen.contains(&node) {
297                return self.annotate(Err(Error::message("recursive alias")));
298            }
299            seen.push(node);
300            let jumps = self.alias_jumps.get().saturating_add(1);
301            self.alias_jumps.set(jumps);
302            if jumps > self.input.semantic_len.saturating_mul(100) {
303                return self.annotate(Err(Error::message("alias repetition limit exceeded")));
304            }
305            let target = self.doc().resolve_alias(node).ok_or_else(|| {
306                Error::message(format!(
307                    "unknown anchor `{}`",
308                    self.doc().alias_name(node).unwrap_or_default()
309                ))
310            });
311            self.node = Some(self.annotate(target)?);
312        }
313        Ok(self)
314    }
315
316    fn child(&self, node: Option<NodeId>, path: String) -> Result<Self> {
317        self.descend(node, path)
318    }
319
320    fn scalar(&self) -> Result<(NodeId, Cow<'input, str>)> {
321        let node = self
322            .node
323            .ok_or_else(|| Error::message("expected a scalar, found null"));
324        let node = self.annotate(node)?;
325        if !matches!(
326            self.doc().semantic_kind(node),
327            Some(SemanticKind::Scalar { .. })
328        ) {
329            return self.annotate(Err(Error::message("expected a scalar value")));
330        }
331        let value = self
332            .doc()
333            .scalar_value(node)
334            .map(|value| (node, value))
335            .map_err(Error::from);
336        self.annotate(value)
337    }
338
339    fn custom_tag(&self) -> Option<String> {
340        if self.ignore_tag {
341            return None;
342        }
343        let raw = self.node.and_then(|node| self.doc().raw_tag(node))?;
344        if raw.starts_with("!!") || raw.starts_with("!<") || !raw.starts_with('!') {
345            return None;
346        }
347        let tag = raw.strip_prefix('!')?;
348        (!tag.is_empty()).then(|| tag.to_owned())
349    }
350
351    fn scalar_kind(&self) -> Result<ScalarKind> {
352        let Some(node) = self.node else {
353            return Ok(ScalarKind::Null);
354        };
355        let style = match self.doc().semantic_kind(node) {
356            Some(SemanticKind::Scalar { style }) => style,
357            _ => return Err(Error::message("expected a scalar value")),
358        };
359        let value = self.doc().scalar_value(node).map_err(Error::from)?;
360        let tag = self
361            .doc()
362            .resolved_tag(node)
363            .map_err(Error::from)?
364            .map(Cow::into_owned);
365        let resolved = resolve_scalar(&value, style, tag.as_deref())
366            .map_err(|error| Error::message(error.to_string()))?;
367        self.annotate(scalar_kind_from_resolved(resolved))
368    }
369
370    fn borrowed_scalar(&self, node: NodeId) -> Option<&'de str> {
371        let source = self.input.borrowed?;
372        let span = self.doc().borrowable_scalar_span(node).ok()??;
373        source.get(span.start as usize..span.end as usize)
374    }
375
376    fn is_empty_plain(&self) -> bool {
377        let Some(node) = self.node else {
378            return true;
379        };
380        matches!(
381            self.doc().semantic_kind(node),
382            Some(SemanticKind::Scalar {
383                style: YamlScalarStyle::Plain
384            })
385        ) && self
386            .doc()
387            .scalar_value(node)
388            .is_ok_and(|value| value.is_empty())
389    }
390}
391
392enum ScalarKind {
393    Null,
394    Bool(bool),
395    Signed(i128),
396    Unsigned(u128),
397    Float(f64),
398    String,
399}
400
401fn scalar_kind_from_resolved(value: ResolvedScalar) -> Result<ScalarKind> {
402    match value {
403        ResolvedScalar::Null => Ok(ScalarKind::Null),
404        ResolvedScalar::Bool(value) => Ok(ScalarKind::Bool(value)),
405        ResolvedScalar::Number(number) if number.has_integer_syntax() => {
406            if let Some(value) = number.as_i128()
407                && value < 0
408            {
409                Ok(ScalarKind::Signed(value))
410            } else if let Some(value) = number.as_u128() {
411                Ok(ScalarKind::Unsigned(value))
412            } else if let Some(value) = number.as_i128() {
413                Ok(ScalarKind::Signed(value))
414            } else {
415                Err(Error::message("integer is outside the supported range"))
416            }
417        }
418        ResolvedScalar::Number(number) => number
419            .as_f64()
420            .map(ScalarKind::Float)
421            .ok_or_else(|| Error::message("float is outside the supported range")),
422        ResolvedScalar::NonFinite(NonFiniteFloat::PositiveInfinity) => {
423            Ok(ScalarKind::Float(f64::INFINITY))
424        }
425        ResolvedScalar::NonFinite(NonFiniteFloat::NegativeInfinity) => {
426            Ok(ScalarKind::Float(f64::NEG_INFINITY))
427        }
428        ResolvedScalar::NonFinite(NonFiniteFloat::NaN) => Ok(ScalarKind::Float(f64::NAN)),
429        ResolvedScalar::String => Ok(ScalarKind::String),
430    }
431}
432
433impl<'de> de::Deserializer<'de> for NodeDeserializer<'_, 'de> {
434    type Error = Error;
435
436    fn deserialize_any<V>(self, visitor: V) -> Result<V::Value>
437    where
438        V: Visitor<'de>,
439    {
440        let this = self.resolved()?;
441        if let Some(variant) = this.custom_tag() {
442            return visitor.visit_enum(YamlEnumAccess { de: this, variant });
443        }
444        let result = match this.node.and_then(|node| this.doc().semantic_kind(node)) {
445            None => visitor.visit_unit(),
446            Some(SemanticKind::Scalar { .. }) => match this.scalar_kind()? {
447                ScalarKind::Null => visitor.visit_unit(),
448                ScalarKind::Bool(value) => visitor.visit_bool(value),
449                ScalarKind::Signed(value) => visitor.visit_i128(value),
450                ScalarKind::Unsigned(value) => visitor.visit_u128(value),
451                ScalarKind::Float(value) => visitor.visit_f64(value),
452                ScalarKind::String => this.clone().deserialize_str(visitor),
453            },
454            Some(SemanticKind::Sequence { .. }) => this.clone().deserialize_seq(visitor),
455            Some(SemanticKind::Mapping { .. }) => this.clone().deserialize_map(visitor),
456            Some(SemanticKind::Alias) => unreachable!("aliases were resolved"),
457            Some(SemanticKind::Document) => Err(Error::message("unexpected document node")),
458        };
459        this.annotate(result)
460    }
461
462    fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value>
463    where
464        V: Visitor<'de>,
465    {
466        let this = self.resolved()?;
467        let result = match this.scalar_kind()? {
468            ScalarKind::Bool(value) => visitor.visit_bool(value),
469            _ => Err(Error::message("expected a boolean")),
470        };
471        this.annotate(result)
472    }
473
474    fn deserialize_i8<V>(self, visitor: V) -> Result<V::Value>
475    where
476        V: Visitor<'de>,
477    {
478        deserialize_signed(self, visitor, |v| i8::try_from(v).ok(), Visitor::visit_i8)
479    }
480    fn deserialize_i16<V>(self, visitor: V) -> Result<V::Value>
481    where
482        V: Visitor<'de>,
483    {
484        deserialize_signed(self, visitor, |v| i16::try_from(v).ok(), Visitor::visit_i16)
485    }
486    fn deserialize_i32<V>(self, visitor: V) -> Result<V::Value>
487    where
488        V: Visitor<'de>,
489    {
490        deserialize_signed(self, visitor, |v| i32::try_from(v).ok(), Visitor::visit_i32)
491    }
492    fn deserialize_i64<V>(self, visitor: V) -> Result<V::Value>
493    where
494        V: Visitor<'de>,
495    {
496        deserialize_signed(self, visitor, |v| i64::try_from(v).ok(), Visitor::visit_i64)
497    }
498    fn deserialize_i128<V>(self, visitor: V) -> Result<V::Value>
499    where
500        V: Visitor<'de>,
501    {
502        deserialize_signed(self, visitor, Some, Visitor::visit_i128)
503    }
504    fn deserialize_u8<V>(self, visitor: V) -> Result<V::Value>
505    where
506        V: Visitor<'de>,
507    {
508        deserialize_unsigned(self, visitor, |v| u8::try_from(v).ok(), Visitor::visit_u8)
509    }
510    fn deserialize_u16<V>(self, visitor: V) -> Result<V::Value>
511    where
512        V: Visitor<'de>,
513    {
514        deserialize_unsigned(self, visitor, |v| u16::try_from(v).ok(), Visitor::visit_u16)
515    }
516    fn deserialize_u32<V>(self, visitor: V) -> Result<V::Value>
517    where
518        V: Visitor<'de>,
519    {
520        deserialize_unsigned(self, visitor, |v| u32::try_from(v).ok(), Visitor::visit_u32)
521    }
522    fn deserialize_u64<V>(self, visitor: V) -> Result<V::Value>
523    where
524        V: Visitor<'de>,
525    {
526        deserialize_unsigned(self, visitor, |v| u64::try_from(v).ok(), Visitor::visit_u64)
527    }
528    fn deserialize_u128<V>(self, visitor: V) -> Result<V::Value>
529    where
530        V: Visitor<'de>,
531    {
532        deserialize_unsigned(self, visitor, Some, Visitor::visit_u128)
533    }
534
535    fn deserialize_f32<V>(self, visitor: V) -> Result<V::Value>
536    where
537        V: Visitor<'de>,
538    {
539        deserialize_float(self, visitor, |visitor, value| {
540            visitor.visit_f32(value as f32)
541        })
542    }
543
544    fn deserialize_f64<V>(self, visitor: V) -> Result<V::Value>
545    where
546        V: Visitor<'de>,
547    {
548        deserialize_float(self, visitor, Visitor::visit_f64)
549    }
550
551    fn deserialize_char<V>(self, visitor: V) -> Result<V::Value>
552    where
553        V: Visitor<'de>,
554    {
555        let this = self.resolved()?;
556        let (_, value) = this.scalar()?;
557        let mut chars = value.chars();
558        let value = chars
559            .next()
560            .filter(|_| chars.next().is_none())
561            .ok_or_else(|| Error::message("expected a single character"));
562        this.annotate(value.and_then(|value| visitor.visit_char(value)))
563    }
564
565    fn deserialize_str<V>(self, visitor: V) -> Result<V::Value>
566    where
567        V: Visitor<'de>,
568    {
569        let this = self.resolved()?;
570        let (node, value) = this.scalar()?;
571        let result = if let Some(value) = this.borrowed_scalar(node) {
572            visitor.visit_borrowed_str(value)
573        } else {
574            match value {
575                Cow::Borrowed(value) => visitor.visit_str(value),
576                Cow::Owned(value) => visitor.visit_string(value),
577            }
578        };
579        this.annotate(result)
580    }
581
582    fn deserialize_string<V>(self, visitor: V) -> Result<V::Value>
583    where
584        V: Visitor<'de>,
585    {
586        let this = self.resolved()?;
587        let (_, value) = this.scalar()?;
588        this.annotate(visitor.visit_string(value.into_owned()))
589    }
590
591    fn deserialize_bytes<V>(self, _visitor: V) -> Result<V::Value>
592    where
593        V: Visitor<'de>,
594    {
595        Err(Error::message(
596            "serialization and deserialization of bytes in YAML is not implemented",
597        ))
598    }
599
600    fn deserialize_byte_buf<V>(self, _visitor: V) -> Result<V::Value>
601    where
602        V: Visitor<'de>,
603    {
604        Err(Error::message(
605            "serialization and deserialization of bytes in YAML is not implemented",
606        ))
607    }
608
609    fn deserialize_option<V>(self, visitor: V) -> Result<V::Value>
610    where
611        V: Visitor<'de>,
612    {
613        let this = self.resolved()?;
614        if matches!(this.scalar_kind(), Ok(ScalarKind::Null)) {
615            this.annotate(visitor.visit_none())
616        } else {
617            visitor.visit_some(this)
618        }
619    }
620
621    fn deserialize_unit<V>(self, visitor: V) -> Result<V::Value>
622    where
623        V: Visitor<'de>,
624    {
625        let this = self.resolved()?;
626        let result = if matches!(this.scalar_kind(), Ok(ScalarKind::Null)) {
627            visitor.visit_unit()
628        } else {
629            Err(Error::message("expected null"))
630        };
631        this.annotate(result)
632    }
633
634    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
635    where
636        V: Visitor<'de>,
637    {
638        self.deserialize_unit(visitor)
639    }
640
641    fn deserialize_newtype_struct<V>(self, _name: &'static str, visitor: V) -> Result<V::Value>
642    where
643        V: Visitor<'de>,
644    {
645        visitor.visit_newtype_struct(self)
646    }
647
648    fn deserialize_seq<V>(self, visitor: V) -> Result<V::Value>
649    where
650        V: Visitor<'de>,
651    {
652        let this = self.resolved()?;
653        if this.is_empty_plain() {
654            return this.annotate(visitor.visit_seq(EmptyAccess));
655        }
656        let node = this
657            .node
658            .ok_or_else(|| Error::message("expected a sequence"))?;
659        if !matches!(
660            this.doc().semantic_kind(node),
661            Some(SemanticKind::Sequence { .. })
662        ) {
663            return this.annotate(Err(Error::message("expected a sequence")));
664        }
665        let items = this.doc().sequence_items(node).collect::<Vec<_>>();
666        let context = this.clone();
667        context.annotate(visitor.visit_seq(YamlSeqAccess {
668            de: this,
669            items,
670            index: 0,
671        }))
672    }
673
674    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> Result<V::Value>
675    where
676        V: Visitor<'de>,
677    {
678        self.deserialize_seq(visitor)
679    }
680
681    fn deserialize_tuple_struct<V>(
682        self,
683        _name: &'static str,
684        _len: usize,
685        visitor: V,
686    ) -> Result<V::Value>
687    where
688        V: Visitor<'de>,
689    {
690        self.deserialize_seq(visitor)
691    }
692
693    fn deserialize_map<V>(self, visitor: V) -> Result<V::Value>
694    where
695        V: Visitor<'de>,
696    {
697        let this = self.resolved()?;
698        if this.is_empty_plain() {
699            return this.annotate(visitor.visit_map(EmptyAccess));
700        }
701        let node = this
702            .node
703            .ok_or_else(|| Error::message("expected a mapping"))?;
704        if !matches!(
705            this.doc().semantic_kind(node),
706            Some(SemanticKind::Mapping { .. })
707        ) {
708            return this.annotate(Err(Error::message("expected a mapping")));
709        }
710        let entries = this.doc().mapping_entries(node).collect::<Vec<_>>();
711        let context = this.clone();
712        context.annotate(visitor.visit_map(YamlMapAccess {
713            de: this,
714            entries,
715            index: 0,
716            pending: None,
717        }))
718    }
719
720    fn deserialize_struct<V>(
721        self,
722        _name: &'static str,
723        _fields: &'static [&'static str],
724        visitor: V,
725    ) -> Result<V::Value>
726    where
727        V: Visitor<'de>,
728    {
729        self.deserialize_map(visitor)
730    }
731
732    fn deserialize_enum<V>(
733        self,
734        _name: &'static str,
735        _variants: &'static [&'static str],
736        visitor: V,
737    ) -> Result<V::Value>
738    where
739        V: Visitor<'de>,
740    {
741        let this = self.resolved()?;
742        let variant = if let Some(variant) = this.custom_tag() {
743            variant
744        } else {
745            let (_, value) = this.scalar()?;
746            value.into_owned()
747        };
748        let context = this.clone();
749        context.annotate(visitor.visit_enum(YamlEnumAccess { de: this, variant }))
750    }
751
752    fn deserialize_identifier<V>(self, visitor: V) -> Result<V::Value>
753    where
754        V: Visitor<'de>,
755    {
756        self.deserialize_str(visitor)
757    }
758
759    fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value>
760    where
761        V: Visitor<'de>,
762    {
763        visitor.visit_unit()
764    }
765
766    fn is_human_readable(&self) -> bool {
767        true
768    }
769}
770
771fn signed_value(kind: ScalarKind) -> Option<i128> {
772    match kind {
773        ScalarKind::Signed(value) => Some(value),
774        ScalarKind::Unsigned(value) => i128::try_from(value).ok(),
775        _ => None,
776    }
777}
778
779fn unsigned_value(kind: ScalarKind) -> Option<u128> {
780    match kind {
781        ScalarKind::Unsigned(value) => Some(value),
782        ScalarKind::Signed(value) => u128::try_from(value).ok(),
783        _ => None,
784    }
785}
786
787fn deserialize_signed<'de, V, T>(
788    de: NodeDeserializer<'_, 'de>,
789    visitor: V,
790    convert: impl FnOnce(i128) -> Option<T>,
791    visit: impl FnOnce(V, T) -> Result<V::Value>,
792) -> Result<V::Value>
793where
794    V: Visitor<'de>,
795{
796    let de = de.resolved()?;
797    let value = signed_value(de.scalar_kind()?)
798        .and_then(convert)
799        .ok_or_else(|| Error::message("expected an integer in range"));
800    de.annotate(value.and_then(|value| visit(visitor, value)))
801}
802
803fn deserialize_unsigned<'de, V, T>(
804    de: NodeDeserializer<'_, 'de>,
805    visitor: V,
806    convert: impl FnOnce(u128) -> Option<T>,
807    visit: impl FnOnce(V, T) -> Result<V::Value>,
808) -> Result<V::Value>
809where
810    V: Visitor<'de>,
811{
812    let de = de.resolved()?;
813    let value = unsigned_value(de.scalar_kind()?)
814        .and_then(convert)
815        .ok_or_else(|| Error::message("expected an unsigned integer in range"));
816    de.annotate(value.and_then(|value| visit(visitor, value)))
817}
818
819fn deserialize_float<'de, V>(
820    de: NodeDeserializer<'_, 'de>,
821    visitor: V,
822    visit: impl FnOnce(V, f64) -> Result<V::Value>,
823) -> Result<V::Value>
824where
825    V: Visitor<'de>,
826{
827    let de = de.resolved()?;
828    let value = match de.scalar_kind()? {
829        ScalarKind::Float(value) => Some(value),
830        ScalarKind::Signed(value) => Some(value as f64),
831        ScalarKind::Unsigned(value) => Some(value as f64),
832        _ => None,
833    }
834    .ok_or_else(|| Error::message("expected a number"));
835    de.annotate(value.and_then(|value| visit(visitor, value)))
836}
837
838struct EmptyAccess;
839
840impl<'de> SeqAccess<'de> for EmptyAccess {
841    type Error = Error;
842    fn next_element_seed<T>(&mut self, _seed: T) -> Result<Option<T::Value>>
843    where
844        T: DeserializeSeed<'de>,
845    {
846        Ok(None)
847    }
848}
849
850impl<'de> MapAccess<'de> for EmptyAccess {
851    type Error = Error;
852    fn next_key_seed<K>(&mut self, _seed: K) -> Result<Option<K::Value>>
853    where
854        K: DeserializeSeed<'de>,
855    {
856        Ok(None)
857    }
858    fn next_value_seed<V>(&mut self, _seed: V) -> Result<V::Value>
859    where
860        V: DeserializeSeed<'de>,
861    {
862        Err(Error::message("value requested without a key"))
863    }
864}
865
866struct YamlSeqAccess<'input, 'de> {
867    de: NodeDeserializer<'input, 'de>,
868    items: Vec<NodeId>,
869    index: usize,
870}
871
872impl<'de> SeqAccess<'de> for YamlSeqAccess<'_, 'de> {
873    type Error = Error;
874    fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>>
875    where
876        T: DeserializeSeed<'de>,
877    {
878        let Some(node) = self.items.get(self.index).copied() else {
879            return Ok(None);
880        };
881        let index = self.index;
882        self.index += 1;
883        let child = self
884            .de
885            .child(Some(node), format!("{}[{index}]", self.de.path))?;
886        seed.deserialize(child).map(Some)
887    }
888    fn size_hint(&self) -> Option<usize> {
889        Some(self.items.len().saturating_sub(self.index))
890    }
891}
892
893struct YamlMapAccess<'input, 'de> {
894    de: NodeDeserializer<'input, 'de>,
895    entries: Vec<(NodeId, NodeId)>,
896    index: usize,
897    pending: Option<(NodeId, String)>,
898}
899
900impl<'de> MapAccess<'de> for YamlMapAccess<'_, 'de> {
901    type Error = Error;
902    fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>>
903    where
904        K: DeserializeSeed<'de>,
905    {
906        let Some((key, value)) = self.entries.get(self.index).copied() else {
907            return Ok(None);
908        };
909        self.index += 1;
910        let key_name = self
911            .de
912            .doc()
913            .scalar_value(key)
914            .ok()
915            .map_or_else(|| "?".to_owned(), Cow::into_owned);
916        let path = if key_name
917            .chars()
918            .all(|c| c.is_alphanumeric() || c == '_' || c == '-')
919        {
920            format!("{}.{}", self.de.path.trim_end_matches('.'), key_name)
921        } else {
922            format!("{}[{:?}]", self.de.path, key_name)
923        };
924        self.pending = Some((value, path));
925        let child = self
926            .de
927            .child(Some(key), format!("{}.<key>", self.de.path))?;
928        seed.deserialize(child).map(Some)
929    }
930    fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value>
931    where
932        V: DeserializeSeed<'de>,
933    {
934        let (node, path) = self
935            .pending
936            .take()
937            .ok_or_else(|| Error::message("value requested without a key"))?;
938        seed.deserialize(self.de.child(Some(node), path)?)
939    }
940    fn size_hint(&self) -> Option<usize> {
941        Some(self.entries.len().saturating_sub(self.index))
942    }
943}
944
945struct YamlEnumAccess<'input, 'de> {
946    de: NodeDeserializer<'input, 'de>,
947    variant: String,
948}
949
950impl<'input, 'de> EnumAccess<'de> for YamlEnumAccess<'input, 'de> {
951    type Error = Error;
952    type Variant = YamlVariantAccess<'input, 'de>;
953    fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self::Variant)>
954    where
955        V: DeserializeSeed<'de>,
956    {
957        let variant = seed.deserialize(serde::de::value::StrDeserializer::<Error>::new(
958            self.variant.as_str(),
959        ))?;
960        Ok((variant, YamlVariantAccess { de: self.de }))
961    }
962}
963
964struct YamlVariantAccess<'input, 'de> {
965    de: NodeDeserializer<'input, 'de>,
966}
967
968impl<'de> VariantAccess<'de> for YamlVariantAccess<'_, 'de> {
969    type Error = Error;
970    fn unit_variant(self) -> Result<()> {
971        Ok(())
972    }
973    fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value>
974    where
975        T: DeserializeSeed<'de>,
976    {
977        let mut de = self.de;
978        de.ignore_tag = true;
979        seed.deserialize(de)
980    }
981    fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value>
982    where
983        V: Visitor<'de>,
984    {
985        let mut de = self.de;
986        de.ignore_tag = true;
987        de.deserialize_tuple(len, visitor)
988    }
989    fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value>
990    where
991        V: Visitor<'de>,
992    {
993        let mut de = self.de;
994        de.ignore_tag = true;
995        de.deserialize_struct("", fields, visitor)
996    }
997}