Skip to main content

deser_yaml/
de.rs

1use std::borrow::Cow;
2use std::collections::{HashMap, HashSet};
3use std::marker::PhantomData;
4use std::sync::Arc;
5
6use deser_core::de::{self, Deserialize, DeserializeDriver, deserialize_value};
7use deser_core::hints::Layout;
8use deser_core::{Atom, Error, ErrorKind, Event, Implicit, ImplicitValue, Source, TrackLocations};
9
10use crate::event::{Event as YamlEvent, EventKind, Mark, ScalarStyle};
11use crate::parser::{Parser, error_at};
12use crate::resolve::{ScalarTag, Version};
13use crate::resolve::{
14    classify_tag, is_collection_tag, resolve_plain, resolve_plain_implicit, resolve_standard,
15};
16use crate::tag::NodeTag;
17
18/// The default for [`DeserializerConfig::set_alias_limit`].
19const DEFAULT_ALIAS_LIMIT: usize = 1_000_000;
20
21/// Configures how YAML is deserialized.
22///
23/// The configuration is independent of the input so it can be created once
24/// (even as a constant) and used for many inputs.  The methods
25/// [`from_str`](Self::from_str) and [`from_slice`](Self::from_slice) work
26/// like the functions of the same name.  To read multiple documents with
27/// the configuration create a [`Deserializer`] with
28/// [`Deserializer::from_str_with_config`] or
29/// [`Deserializer::from_slice_with_config`].
30///
31/// ```
32/// use deser_yaml::{DeserializerConfig, Version};
33///
34/// const CONFIG: DeserializerConfig = DeserializerConfig::builder()
35///     .version(Version::V1_1).build();
36/// let (flag, mode): (bool, u32) = CONFIG.from_str("[yes, 0777]").unwrap();
37/// assert_eq!((flag, mode), (true, 0o777));
38/// ```
39#[derive(Debug, Clone, PartialEq, Eq)]
40pub struct DeserializerConfig {
41    version: Version,
42    alias_limit: usize,
43    merge_keys: bool,
44
45    context: deser_core::Context,
46}
47
48impl Default for DeserializerConfig {
49    fn default() -> DeserializerConfig {
50        DeserializerConfig::new()
51    }
52}
53
54impl DeserializerConfig {
55    /// Creates the default configuration.
56    pub const fn new() -> DeserializerConfig {
57        DeserializerConfig {
58            version: Version::V1_2,
59            alias_limit: DEFAULT_ALIAS_LIMIT,
60            merge_keys: true,
61
62            context: deser_core::Context::new(),
63        }
64    }
65
66    /// Returns a builder for the configuration (see [`DeserializerConfigBuilder`]).
67    pub const fn builder() -> DeserializerConfigBuilder {
68        DeserializerConfigBuilder::new()
69    }
70
71    /// Returns a builder that starts with this configuration.
72    pub const fn into_builder(self) -> DeserializerConfigBuilder {
73        DeserializerConfigBuilder { value: self }
74    }
75
76    /// Sets the context the values are deserialized in.
77    ///
78    /// The values of the context are the defaults of the extension values
79    /// of the state (see [`Context`](deser_core::Context)), for instance
80    /// the variants of open enums.  The deserializers and readers created
81    /// with the configuration use this context.  A context set
82    /// on the driver takes precedence.
83    pub fn set_context(&mut self, context: deser_core::Context) {
84        self.context = context;
85    }
86
87    /// Returns the configuration without its context (for the frames of
88    /// streams, which get the context of the stream).
89    pub(crate) fn without_context(&self) -> DeserializerConfig {
90        let mut config = self.clone();
91        config.context = deser_core::Context::default();
92        config
93    }
94
95    /// Returns the context the values are deserialized in.
96    pub fn context(&self) -> &deser_core::Context {
97        &self.context
98    }
99
100    /// Sets the YAML version for documents that do not declare one.
101    ///
102    /// The version determines how plain scalars are resolved.  Documents
103    /// that start with a `%YAML` directive use the version they declare.  The
104    /// default is [`Version::V1_2`].
105    pub const fn set_version(&mut self, version: Version) {
106        self.version = version;
107    }
108
109    /// Limits the number of events that aliases can expand to per document.
110    ///
111    /// Every scalar and every start and end of a collection that is replayed
112    /// for an alias counts as one event.  The default is 1,000,000.
113    pub const fn set_alias_limit(&mut self, limit: usize) {
114        self.alias_limit = limit;
115    }
116
117    /// Enables or disables merge keys.
118    ///
119    /// Merge keys (`<<`) insert the entries of other mappings into a
120    /// mapping.  They are defined for YAML 1.1 but widely used with all
121    /// versions of YAML, which is why they are enabled by default:
122    ///
123    /// ```
124    /// use std::collections::BTreeMap;
125    /// use deser::Deserialize;
126    ///
127    /// #[derive(Deserialize)]
128    /// struct Service {
129    ///     image: String,
130    ///     replicas: u32,
131    /// }
132    ///
133    /// let input = "
134    /// base: &base {image: app, replicas: 1}
135    /// web:
136    ///   <<: *base
137    ///   replicas: 3
138    /// ";
139    /// let value: BTreeMap<String, Service> =
140    ///     deser_yaml::from_str(input).unwrap();
141    /// assert_eq!(value["web"].image, "app");
142    /// assert_eq!(value["web"].replicas, 3);
143    /// ```
144    ///
145    /// Only a plain `<<` is a merge key (`"<<"` is a regular key).  Its value
146    /// must be a mapping or a sequence of mappings.  Keys of the mapping take
147    /// precedence over merged keys, and with multiple mappings the earlier
148    /// ones take precedence.  The merged entries are emitted after the
149    /// entries of the mapping.
150    ///
151    /// When disabled, `<<` is a regular key.
152    pub const fn set_merge_keys(&mut self, yes: bool) {
153        self.merge_keys = yes;
154    }
155
156    /// Deserializes a value from YAML.
157    ///
158    /// See [`from_str`].
159    pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
160        deserialize_value(|driver| self.drive_str(s, driver))
161    }
162
163    /// The part of [`from_str`](Self::from_str) that does not depend on the
164    /// type of the value, it exists once.
165    fn drive_str<'de>(
166        &self,
167        s: &'de str,
168        driver: &mut DeserializeDriver<'_, 'de>,
169    ) -> Result<(), Error> {
170        drive_single(Deserializer::from_str_with_config(s, self.clone()), driver)
171    }
172
173    /// Deserializes a value from YAML in a byte slice.
174    ///
175    /// See [`from_slice`].
176    pub fn from_slice<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result<T, Error> {
177        deserialize_value(|driver| self.drive_slice(bytes, driver))
178    }
179
180    /// The part of [`from_slice`](Self::from_slice) that does not depend on
181    /// the type of the value, it exists once.
182    fn drive_slice<'de>(
183        &self,
184        bytes: &'de [u8],
185        driver: &mut DeserializeDriver<'_, 'de>,
186    ) -> Result<(), Error> {
187        drive_single(
188            Deserializer::from_slice_with_config(bytes, self.clone()),
189            driver,
190        )
191    }
192}
193
194/// Builds a [`DeserializerConfig`].
195///
196/// The methods have the names of the setters of [`DeserializerConfig`] (without `set_`).
197#[derive(Debug, Clone)]
198#[must_use]
199pub struct DeserializerConfigBuilder {
200    value: DeserializerConfig,
201}
202
203impl DeserializerConfigBuilder {
204    /// Creates a builder that starts with the default.
205    pub const fn new() -> DeserializerConfigBuilder {
206        DeserializerConfigBuilder {
207            value: DeserializerConfig::new(),
208        }
209    }
210
211    /// Sets the YAML version for documents that do not declare one.
212    ///
213    /// See [`DeserializerConfig::set_version`].
214    pub const fn version(mut self, version: Version) -> DeserializerConfigBuilder {
215        self.value.set_version(version);
216        self
217    }
218
219    /// Limits the number of events that aliases can expand to per document.
220    ///
221    /// See [`DeserializerConfig::set_alias_limit`].
222    pub const fn alias_limit(mut self, limit: usize) -> DeserializerConfigBuilder {
223        self.value.set_alias_limit(limit);
224        self
225    }
226
227    /// Enables or disables merge keys.
228    ///
229    /// See [`DeserializerConfig::set_merge_keys`].
230    pub const fn merge_keys(mut self, yes: bool) -> DeserializerConfigBuilder {
231        self.value.set_merge_keys(yes);
232        self
233    }
234
235    /// Sets the context the values are deserialized in.
236    ///
237    /// See [`DeserializerConfig::set_context`].
238    pub fn context(mut self, context: deser_core::Context) -> DeserializerConfigBuilder {
239        self.value.set_context(context);
240        self
241    }
242
243    /// Returns the built [`DeserializerConfig`].
244    pub const fn build(self) -> DeserializerConfig {
245        // the value cannot be moved out of the builder in a const fn as the
246        // builder needs dropping (the context has a destructor)
247        // SAFETY: the value is read once and the builder is forgotten
248        let value = unsafe { core::ptr::read(&self.value) };
249        core::mem::forget(self);
250        value
251    }
252}
253
254impl Default for DeserializerConfigBuilder {
255    fn default() -> DeserializerConfigBuilder {
256        DeserializerConfigBuilder::new()
257    }
258}
259
260/// Deserializes YAML.
261///
262/// A YAML stream can contain multiple documents.  Every call to
263/// [`deserialize`](Self::deserialize) reads the next document:
264///
265/// ```
266/// use deser_yaml::Deserializer;
267///
268/// let mut de = Deserializer::from_str("--- 1\n--- two\n");
269/// assert_eq!(de.deserialize::<u32>().unwrap(), 1);
270/// assert_eq!(de.deserialize::<String>().unwrap(), "two");
271/// assert!(de.is_end());
272/// ```
273///
274/// To deserialize a single document, use [`from_str`] and
275/// [`from_slice`] (or the methods of the same name on
276/// [`DeserializerConfig`]).
277///
278/// # Aliases
279///
280/// Aliases (`*name`) are expanded: the events of the anchored node are
281/// replayed.  To protect against inputs that expand exponentially (the
282/// "billion laughs" attack) the number of events produced by aliases is
283/// limited, see [`DeserializerConfig::set_alias_limit`].
284pub struct Deserializer<'a> {
285    input: &'a str,
286    parser: Parser<'a>,
287    peeked: Option<YamlEvent<'a>>,
288    started: bool,
289    /// An error that is reported by the next call.
290    pending_error: Option<Error>,
291    /// The parser failed, no further documents can be read.
292    failed: bool,
293    config: DeserializerConfig,
294    /// Merge keys are enabled and the input contains `<<`.  Otherwise
295    /// there cannot be merge keys.
296    track_merges: bool,
297    /// The input as source for location tracking, shared by all documents.
298    source: Option<Arc<str>>,
299    doc: Document<'a>,
300}
301
302/// A node event as it is recorded for anchors.
303#[derive(Clone)]
304enum Node<'a> {
305    Scalar {
306        tag: Option<Cow<'a, str>>,
307        style: ScalarStyle,
308        value: Cow<'a, str>,
309        start: Mark,
310        end: usize,
311    },
312    Start {
313        tag: Option<Cow<'a, str>>,
314        is_map: bool,
315        /// `true` for flow collections (`[a]` and `{a: b}`).
316        flow: bool,
317        start: Mark,
318        end: usize,
319    },
320    End {
321        is_map: bool,
322        start: Mark,
323        end: usize,
324    },
325    /// An alias, resolved to the range of the anchored node in the
326    /// recorded nodes.
327    Alias { range: (usize, usize) },
328}
329
330/// The per document state.
331#[derive(Default)]
332struct Document<'a> {
333    version: Version,
334    /// The recorded nodes.  Nodes are only recorded while an anchored
335    /// collection is open.  Nested anchors share the recording.
336    nodes: Vec<Node<'a>>,
337    /// The anchors and the range of their nodes in `nodes`.
338    anchors: HashMap<Cow<'a, str>, (usize, usize)>,
339    /// The collections that are currently recorded.
340    open: Vec<OpenNode<'a>>,
341    /// The range of the last collection that was captured (recorded
342    /// without anchor, for merge keys).
343    captured: Option<(usize, usize)>,
344    /// The depth of the collections from the parser (without aliases).
345    depth: usize,
346}
347
348/// A collection that is being recorded.
349struct OpenNode<'a> {
350    anchor: Option<Cow<'a, str>>,
351    /// The index of the start node in the recording.
352    start: usize,
353    /// The depth of the collection.
354    depth: usize,
355    /// The range should be stored in `captured` when the collection ends.
356    capture: bool,
357}
358
359impl<'a> Document<'a> {
360    fn reset(&mut self, version: Version) {
361        self.version = version;
362        self.nodes.clear();
363        self.anchors.clear();
364        self.open.clear();
365        self.captured = None;
366        self.depth = 0;
367    }
368
369    /// Turns a parser event into a node and records anchors.
370    ///
371    /// If `capture` is set, a collection is recorded even without anchor
372    /// and its range is stored in `captured` once it ends.
373    fn record(&mut self, event: YamlEvent<'a>, capture: bool) -> Result<Node<'a>, Error> {
374        let start = event.start;
375        let end = event.end.offset;
376        let is_map = matches!(event.kind, EventKind::MappingStart { .. });
377        let (node, anchor) = match event.kind {
378            EventKind::Scalar {
379                props,
380                style,
381                value,
382            } => (
383                Node::Scalar {
384                    tag: props.tag,
385                    style,
386                    value,
387                    start,
388                    end,
389                },
390                props.anchor,
391            ),
392            EventKind::SequenceStart { props, flow } | EventKind::MappingStart { props, flow } => {
393                self.depth += 1;
394                (
395                    Node::Start {
396                        tag: props.tag,
397                        is_map,
398                        flow,
399                        start,
400                        end,
401                    },
402                    props.anchor,
403                )
404            }
405            EventKind::SequenceEnd | EventKind::MappingEnd => {
406                let is_map = event.kind == EventKind::MappingEnd;
407                self.depth -= 1;
408                let node = Node::End { is_map, start, end };
409                if !self.open.is_empty() {
410                    self.nodes.push(node.clone());
411                    let depth = self.depth + 1;
412                    if let Some(open) = self.open.pop_if(|x| x.depth == depth) {
413                        let range = (open.start, self.nodes.len());
414                        if let Some(name) = open.anchor {
415                            self.anchors.insert(name, range);
416                        }
417                        if open.capture {
418                            self.captured = Some(range);
419                        }
420                    }
421                }
422                return Ok(node);
423            }
424            EventKind::Alias { anchor } => {
425                if self.open.iter().any(|x| x.anchor.as_ref() == Some(&anchor)) {
426                    return Err(error_at(start, "recursive alias"));
427                }
428                let range = match self.anchors.get(&anchor) {
429                    Some(&range) => range,
430                    None => return Err(error_at(start, &format!("unknown anchor `{}`", anchor))),
431                };
432                let node = Node::Alias { range };
433                if !self.open.is_empty() {
434                    self.nodes.push(node.clone());
435                }
436                return Ok(node);
437            }
438            _ => unreachable!("unexpected event in document"),
439        };
440
441        let is_start = matches!(node, Node::Start { .. });
442        if anchor.is_some() || (capture && is_start) || !self.open.is_empty() {
443            let index = self.nodes.len();
444            self.nodes.push(node.clone());
445            if is_start && (anchor.is_some() || capture) {
446                self.open.push(OpenNode {
447                    anchor,
448                    start: index,
449                    depth: self.depth,
450                    capture,
451                });
452            } else if let Some(name) = anchor {
453                self.anchors.insert(name, (index, index + 1));
454            }
455        }
456        Ok(node)
457    }
458
459    /// Returns the index after the recorded node that starts at `index`.
460    fn node_end(&self, index: usize) -> usize {
461        if !matches!(self.nodes[index], Node::Start { .. }) {
462            return index + 1;
463        }
464        let mut depth = 0;
465        for (offset, node) in self.nodes[index..].iter().enumerate() {
466            match node {
467                Node::Start { .. } => depth += 1,
468                Node::End { .. } => {
469                    depth -= 1;
470                    if depth == 0 {
471                        return index + offset + 1;
472                    }
473                }
474                _ => {}
475            }
476        }
477        unreachable!("unbalanced recording");
478    }
479
480    /// Follows a recorded alias to the range of the node it refers to.
481    fn resolve_range(&self, mut range: (usize, usize)) -> (usize, usize) {
482        while let Node::Alias { range: target } = self.nodes[range.0] {
483            range = target;
484        }
485        range
486    }
487
488    /// Returns the ranges of the items of a recorded collection.
489    fn items(&self, range: (usize, usize)) -> impl Iterator<Item = (usize, usize)> + '_ {
490        let mut index = range.0 + 1;
491        std::iter::from_fn(move || {
492            if index + 1 >= range.1 {
493                return None;
494            }
495            let item = (index, self.node_end(index));
496            index = item.1;
497            Some(item)
498        })
499    }
500}
501
502/// The identity of a map key for the purpose of merge keys.
503///
504/// Only scalar keys are compared.  Two keys are the same if they resolve to
505/// the same value (so `1` and `0x1` are the same key).
506#[derive(PartialEq, Eq, Hash)]
507enum KeyId<'a> {
508    Null,
509    Bool(bool),
510    /// An integer as sign and magnitude.
511    Int(bool, u128),
512    Float(u64),
513    Str(Cow<'a, str>),
514    Bytes(Vec<u8>),
515    Tagged(Cow<'a, str>, Cow<'a, str>),
516}
517
518impl<'a> KeyId<'a> {
519    fn of_scalar(
520        tag: &Option<Cow<'a, str>>,
521        style: ScalarStyle,
522        value: &Cow<'a, str>,
523        version: Version,
524    ) -> Option<KeyId<'a>> {
525        let atom = match tag {
526            None if style == ScalarStyle::Plain => resolve_plain(value.clone(), version),
527            None => return Some(KeyId::Str(value.clone())),
528            Some(tag) => match classify_tag(tag) {
529                ScalarTag::Str => return Some(KeyId::Str(value.clone())),
530                ScalarTag::Standard(name) => resolve_standard(name, value.clone(), version).ok()?,
531                ScalarTag::Custom => return Some(KeyId::Tagged(tag.clone(), value.clone())),
532            },
533        };
534        Some(match atom {
535            Atom::Null => KeyId::Null,
536            Atom::Bool(value) => KeyId::Bool(value),
537            Atom::U64(value) => KeyId::Int(false, value.into()),
538            Atom::I64(value) => KeyId::Int(value < 0, value.unsigned_abs().into()),
539            Atom::F64(value) => KeyId::Float(value.to_bits()),
540            Atom::Str(value) => KeyId::Str(value.into_cow()),
541            Atom::Bytes(value) => KeyId::Bytes(value.into_owned()),
542            Atom::Ext(ref ext) => {
543                if let Some(&value) = ext.downcast_ref::<u128>() {
544                    KeyId::Int(false, value)
545                } else if let Some(&value) = ext.downcast_ref::<i128>() {
546                    KeyId::Int(value < 0, value.unsigned_abs())
547                } else {
548                    return None;
549                }
550            }
551            _ => return None,
552        })
553    }
554}
555
556fn is_merge_key(tag: &Option<Cow<'_, str>>, style: ScalarStyle, value: &str) -> bool {
557    tag.is_none() && style == ScalarStyle::Plain && value == "<<"
558}
559
560/// Something that is emitted before the next event from the parser.
561enum Pending<'a> {
562    /// A range of recorded nodes (for aliases and merged entries).
563    Range(usize, usize),
564    /// A single node.
565    Node(Node<'a>),
566}
567
568/// An open collection while merge keys are tracked.
569struct Frame<'a> {
570    is_map: bool,
571    /// For maps: the next node is a key.
572    expect_key: bool,
573    /// The keys that were emitted so far.
574    keys: HashSet<KeyId<'a>>,
575    /// The ranges of the merge key values.
576    sources: Vec<(usize, usize)>,
577}
578
579impl<'a> Deserializer<'a> {
580    /// Creates a new deserializer for a string.
581    #[allow(clippy::should_implement_trait)]
582    pub fn from_str(input: &'a str) -> Deserializer<'a> {
583        Deserializer::from_str_with_config(input, DeserializerConfig::new())
584    }
585
586    /// Creates a new deserializer for a string with the given configuration.
587    pub fn from_str_with_config(input: &'a str, config: DeserializerConfig) -> Deserializer<'a> {
588        let track_merges = config.merge_keys && input.contains("<<");
589        Deserializer {
590            input,
591            parser: Parser::new(input),
592            peeked: None,
593            started: false,
594            pending_error: None,
595            failed: false,
596            config,
597            track_merges,
598            source: None,
599            doc: Document::default(),
600        }
601    }
602
603    /// Creates a new deserializer for a byte slice.
604    ///
605    /// The input must be UTF-8, otherwise deserializing fails.
606    pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
607        Deserializer::from_slice_with_config(input, DeserializerConfig::new())
608    }
609
610    /// Creates a new deserializer for a byte slice with the given
611    /// configuration.
612    ///
613    /// The input must be UTF-8, otherwise deserializing fails.
614    pub fn from_slice_with_config(input: &'a [u8], config: DeserializerConfig) -> Deserializer<'a> {
615        match str_from_utf8(input) {
616            Ok(input) => Deserializer::from_str_with_config(input, config),
617            Err(err) => {
618                let mut rv = Deserializer::from_str_with_config("", config);
619                rv.pending_error = Some(err);
620                rv.failed = true;
621                rv
622            }
623        }
624    }
625
626    /// Returns the configuration.
627    pub fn config(&self) -> &DeserializerConfig {
628        &self.config
629    }
630
631    /// Returns `true` if there are no more documents.
632    ///
633    /// If the input is malformed this returns `false` and the next call to
634    /// [`deserialize`](Self::deserialize) reports the error.
635    pub fn is_end(&mut self) -> bool {
636        if self.failed {
637            return self.pending_error.is_none();
638        }
639        match self.peek_event() {
640            Ok(event) => event.kind == EventKind::StreamEnd,
641            Err(err) => {
642                self.pending_error = Some(err);
643                false
644            }
645        }
646    }
647
648    /// Fails if there are more documents.
649    pub fn end(&mut self) -> Result<(), Error> {
650        if self.is_end() {
651            Ok(())
652        } else if let Some(err) = self.pending_error.take() {
653            Err(err)
654        } else {
655            Err(Error::new(
656                ErrorKind::Syntax,
657                "expected a single document, found more",
658            ))
659        }
660    }
661
662    /// Deserializes the next document.
663    ///
664    /// Fails with [`ErrorKind::EndOfFile`] if there are no more documents.
665    /// If a document fails to deserialize (for instance because it does not
666    /// match the type), the rest of the document is skipped and the next
667    /// call continues with the next document.  Syntax errors end the stream.
668    ///
669    /// To configure the deserialization (for instance to add layers) use
670    /// [`deserialize_with`](Self::deserialize_with).
671    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
672        de::Deserializer::deserialize(self)
673    }
674
675    /// Deserializes the next value with a configured driver.
676    ///
677    /// The callback is invoked with the driver before the value is
678    /// deserialized, for instance to add [`Layer`](deser_core::de::Layer)s.
679    pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
680    where
681        T: Deserialize<'a>,
682        F: FnOnce(&mut DeserializeDriver<'_, 'a>),
683    {
684        de::Deserializer::deserialize_with(self, setup)
685    }
686
687    /// Returns an iterator over the remaining documents.
688    ///
689    /// The iterator stops after the first error.
690    ///
691    /// ```
692    /// let mut de = deser_yaml::Deserializer::from_str("--- 1\n--- 2\n--- 3\n");
693    /// let docs = de.iter::<u32>().collect::<Result<Vec<_>, _>>().unwrap();
694    /// assert_eq!(docs, [1, 2, 3]);
695    /// ```
696    pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
697        Iter {
698            de: self,
699            failed: false,
700            _marker: PhantomData,
701        }
702    }
703
704    /// Parses the next document and feeds the events into the given driver.
705    ///
706    /// This is useful to deserialize into a custom
707    /// [`Sink`](deser_core::de::Sink).  See also [`deserialize_with`](Self::deserialize_with).
708    /// Errors carry the location in the input (see [`Error::line`]).
709    ///
710    /// The context of the configuration is given to the driver (values that
711    /// the context of the driver has take precedence, see
712    /// [`DeserializeDriver::set_default_context`]).
713    pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
714        if !self.config.context.is_empty() {
715            driver.set_default_context(self.config.context.clone());
716        }
717        if let Some(err) = self.pending_error.take() {
718            return Err(err);
719        }
720        if self.failed {
721            return Err(Error::new(
722                ErrorKind::InvalidState,
723                "cannot continue after a syntax error",
724            ));
725        }
726
727        let event = self.next_event()?;
728        let version = match event.kind {
729            EventKind::DocumentStart { version, .. } => match version {
730                Some((1, minor)) if minor < 2 => Version::V1_1,
731                Some(_) => Version::V1_2,
732                None => self.config.version,
733            },
734            EventKind::StreamEnd => {
735                // stay at the end of the stream
736                self.peeked = Some(event);
737                return Err(Error::new(ErrorKind::EndOfFile, "no more documents"));
738            }
739            _ => unreachable!("expected document start"),
740        };
741        self.doc.reset(version);
742
743        if TrackLocations::of(driver.state()) {
744            let source = self.source.get_or_insert_with(|| self.input.into());
745            Source(source.clone()).set(driver.state_mut());
746        }
747        let input = self.input;
748        let rv = self.drive_document(driver).map_err(|mut err| {
749            err.resolve_position(input.as_bytes());
750            err
751        });
752
753        if rv.is_err() && !self.failed {
754            // skip the rest of the document so that the next one can be read
755            if let Err(err) = self.skip_document() {
756                self.pending_error = Some(err);
757            }
758        }
759        rv
760    }
761
762    fn ensure_started(&mut self) -> Result<(), Error> {
763        if !self.started {
764            self.started = true;
765            let event = self.parser_event()?;
766            debug_assert_eq!(event.kind, EventKind::StreamStart);
767        }
768        Ok(())
769    }
770
771    fn parser_event(&mut self) -> Result<YamlEvent<'a>, Error> {
772        self.parser.next_event().inspect_err(|_| {
773            self.failed = true;
774        })
775    }
776
777    fn next_event(&mut self) -> Result<YamlEvent<'a>, Error> {
778        self.ensure_started()?;
779        match self.peeked.take() {
780            Some(event) => Ok(event),
781            None => self.parser_event(),
782        }
783    }
784
785    fn peek_event(&mut self) -> Result<&YamlEvent<'a>, Error> {
786        if self.peeked.is_none() {
787            let event = self.next_event()?;
788            self.peeked = Some(event);
789        }
790        Ok(self.peeked.as_ref().unwrap())
791    }
792
793    fn skip_document(&mut self) -> Result<(), Error> {
794        loop {
795            if let EventKind::DocumentEnd { .. } = self.next_event()?.kind {
796                return Ok(());
797            }
798        }
799    }
800
801    fn drive_document(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
802        // nodes that are emitted before the next event from the parser
803        let mut pending: Vec<Pending<'a>> = Vec::new();
804        // the number of nodes produced by aliases and merges
805        let mut replayed = 0;
806        // merge keys need to know the keys of all open maps.  This is only
807        // done if the input can contain merge keys.
808        let track_merges = self.track_merges;
809        let mut frames: Vec<Frame<'a>> = Vec::new();
810        let mut merge_value_follows = false;
811
812        loop {
813            let (node, index) =
814                match self.next_node(&mut pending, &mut replayed, merge_value_follows)? {
815                    Some(rv) => rv,
816                    None => return Ok(()),
817                };
818
819            if merge_value_follows {
820                merge_value_follows = false;
821                let range = self.merge_source(node, index, &mut pending)?;
822                let frame = frames.last_mut().unwrap();
823                frame.sources.push(range);
824                frame.expect_key = true;
825                continue;
826            }
827
828            if track_merges
829                && let Some(frame) = frames.last_mut()
830                && frame.is_map
831            {
832                if frame.expect_key
833                    && let Node::Scalar {
834                        ref tag,
835                        style,
836                        ref value,
837                        ..
838                    } = node
839                {
840                    if is_merge_key(tag, style, value) {
841                        frame.expect_key = false;
842                        merge_value_follows = true;
843                        continue;
844                    }
845                    if let Some(id) = KeyId::of_scalar(tag, style, value, self.doc.version) {
846                        frame.keys.insert(id);
847                    }
848                }
849                // aliases are replayed, their nodes are counted
850                if !matches!(node, Node::Alias { .. } | Node::End { .. }) {
851                    frame.expect_key = !frame.expect_key;
852                }
853            }
854
855            match node {
856                Node::Scalar {
857                    tag,
858                    style,
859                    value,
860                    start,
861                    end,
862                } => {
863                    let version = self.doc.version;
864                    emit_scalar(driver, tag, style, value, version, start, end)?;
865                }
866                Node::Start {
867                    tag,
868                    is_map,
869                    flow,
870                    start,
871                    end,
872                } => {
873                    // flow collections are compact so that they stay flow
874                    // collections when they are serialized again
875                    if flow {
876                        Layout::Compact.set(driver.state_mut());
877                    }
878                    if track_merges {
879                        frames.push(Frame {
880                            is_map,
881                            expect_key: true,
882                            keys: HashSet::new(),
883                            sources: Vec::new(),
884                        });
885                    }
886                    let event = if is_map {
887                        Event::map_start()
888                    } else {
889                        Event::seq_start()
890                    };
891                    driver.state_mut().set_input_range(start.offset, end);
892                    match tag {
893                        Some(tag) => match is_collection_tag(&tag, is_map) {
894                            Ok(true) => driver.emit(event)?,
895                            Ok(false) => emit_tagged(driver, &tag, event)?,
896                            Err(msg) => return Err(error_at(start, msg)),
897                        },
898                        None => driver.emit(event)?,
899                    }
900                }
901                Node::End { is_map, start, end } => {
902                    if track_merges {
903                        let frame = frames.last_mut().unwrap();
904                        if !frame.sources.is_empty() {
905                            // emit the merged entries before the end of the
906                            // map, the end is emitted again afterwards
907                            let sources = std::mem::take(&mut frame.sources);
908                            let entries =
909                                self.merged_entries(&sources, &mut frame.keys, &mut replayed)?;
910                            pending.push(Pending::Node(Node::End { is_map, start, end }));
911                            for (key, value) in entries.into_iter().rev() {
912                                pending.push(Pending::Range(value.0, value.1));
913                                pending.push(Pending::Range(key.0, key.1));
914                            }
915                            continue;
916                        }
917                        frames.pop();
918                    }
919                    let event = if is_map { Event::MapEnd } else { Event::SeqEnd };
920                    driver.state_mut().set_input_range(start.offset, end);
921                    driver.emit(event)?;
922                }
923                Node::Alias { range } => pending.push(Pending::Range(range.0, range.1)),
924            }
925        }
926    }
927
928    /// Returns the next node and its index if it was recorded.  Returns
929    /// `None` at the end of the document.
930    fn next_node(
931        &mut self,
932        pending: &mut Vec<Pending<'a>>,
933        replayed: &mut usize,
934        capture: bool,
935    ) -> Result<Option<(Node<'a>, Option<usize>)>, Error> {
936        loop {
937            let (node, index) = match pending.last_mut() {
938                Some(Pending::Range(start, end)) => {
939                    if start == end {
940                        pending.pop();
941                        continue;
942                    }
943                    let index = *start;
944                    *start += 1;
945                    (self.doc.nodes[index].clone(), Some(index))
946                }
947                Some(Pending::Node(_)) => match pending.pop() {
948                    Some(Pending::Node(node)) => return Ok(Some((node, None))),
949                    _ => unreachable!(),
950                },
951                None => {
952                    let event = self.next_event()?;
953                    if let EventKind::DocumentEnd { .. } = event.kind {
954                        return Ok(None);
955                    }
956                    return Ok(Some((self.doc.record(event, capture)?, None)));
957                }
958            };
959            self.count_replayed(replayed, 1)?;
960            return Ok(Some((node, index)));
961        }
962    }
963
964    fn count_replayed(&self, replayed: &mut usize, count: usize) -> Result<(), Error> {
965        *replayed += count;
966        if *replayed > self.config.alias_limit {
967            Err(Error::new(
968                ErrorKind::LimitExceeded,
969                "aliases expand to too many events",
970            ))
971        } else {
972            Ok(())
973        }
974    }
975
976    /// Consumes the value of a merge key and returns the range of its
977    /// recorded nodes.
978    fn merge_source(
979        &mut self,
980        node: Node<'a>,
981        index: Option<usize>,
982        pending: &mut [Pending<'a>],
983    ) -> Result<(usize, usize), Error> {
984        match node {
985            Node::Alias { range } => Ok(range),
986            Node::Start { .. } => match index {
987                // the value is replayed, skip it
988                Some(index) => {
989                    let end = self.doc.node_end(index);
990                    if let Some(Pending::Range(start, _)) = pending.last_mut() {
991                        *start = end;
992                    }
993                    Ok((index, end))
994                }
995                // the value comes from the parser, record it without
996                // emitting it
997                None => {
998                    while self.doc.captured.is_none() {
999                        let event = self.next_event()?;
1000                        self.doc.record(event, false)?;
1001                    }
1002                    Ok(self.doc.captured.take().unwrap())
1003                }
1004            },
1005            Node::Scalar { start, .. } | Node::End { start, .. } => Err(error_at(
1006                start,
1007                "the value of a merge key must be a mapping or a sequence of mappings",
1008            )),
1009        }
1010    }
1011
1012    /// Returns the entries that the merge keys of a map add.
1013    ///
1014    /// `keys` holds the keys the map already has, the merged keys are added.
1015    /// Earlier sources take precedence over later ones, the merge keys of the
1016    /// sources are applied recursively.
1017    #[allow(clippy::type_complexity)]
1018    fn merged_entries(
1019        &self,
1020        sources: &[(usize, usize)],
1021        keys: &mut HashSet<KeyId<'a>>,
1022        replayed: &mut usize,
1023    ) -> Result<Vec<((usize, usize), (usize, usize))>, Error> {
1024        let mut entries = Vec::new();
1025        // the mappings to merge in reverse order
1026        let mut stack = Vec::new();
1027        self.push_merge_sources(sources, &mut stack);
1028
1029        while let Some(range) = stack.pop() {
1030            match self.doc.nodes[range.0] {
1031                Node::Start { is_map: true, .. } => {}
1032                Node::Start { start, .. } | Node::Scalar { start, .. } => {
1033                    return Err(error_at(
1034                        start,
1035                        "merge keys can only merge mappings or sequences of mappings",
1036                    ));
1037                }
1038                _ => unreachable!(),
1039            }
1040            self.count_replayed(replayed, range.1 - range.0)?;
1041
1042            let mut nested = Vec::new();
1043            let mut items = self.doc.items(range);
1044            while let (Some(key), Some(value)) = (items.next(), items.next()) {
1045                if let Node::Scalar {
1046                    tag: ref key_tag,
1047                    style,
1048                    value: ref key_value,
1049                    ..
1050                } = self.doc.nodes[self.doc.resolve_range(key).0]
1051                {
1052                    if is_merge_key(key_tag, style, key_value) {
1053                        nested.push(value);
1054                        continue;
1055                    }
1056                    let version = self.doc.version;
1057                    if let Some(id) = KeyId::of_scalar(key_tag, style, key_value, version)
1058                        && !keys.insert(id)
1059                    {
1060                        // the map (or an earlier source) has the key
1061                        continue;
1062                    }
1063                }
1064                entries.push((key, value));
1065            }
1066            self.push_merge_sources(&nested, &mut stack);
1067        }
1068        Ok(entries)
1069    }
1070
1071    /// Adds the mappings of merge key values to the stack (in reverse order,
1072    /// so that the first mapping is processed first).
1073    fn push_merge_sources(&self, sources: &[(usize, usize)], stack: &mut Vec<(usize, usize)>) {
1074        for &source in sources.iter().rev() {
1075            let source = self.doc.resolve_range(source);
1076            match self.doc.nodes[source.0] {
1077                Node::Start { is_map: false, .. } => {
1078                    let items: Vec<_> = self
1079                        .doc
1080                        .items(source)
1081                        .map(|item| self.doc.resolve_range(item))
1082                        .collect();
1083                    stack.extend(items.into_iter().rev());
1084                }
1085                _ => stack.push(source),
1086            }
1087        }
1088    }
1089}
1090
1091#[inline]
1092///
1093/// Scalars are emitted borrowed as they are slices of the input unless they
1094/// had to be unescaped or folded.
1095fn emit_scalar<'a>(
1096    driver: &mut DeserializeDriver<'_, 'a>,
1097    tag: Option<Cow<'_, str>>,
1098    style: ScalarStyle,
1099    value: Cow<'a, str>,
1100    version: Version,
1101    start: Mark,
1102    end: usize,
1103) -> Result<(), Error> {
1104    driver.state_mut().set_input_range(start.offset, end);
1105    let tag = match tag {
1106        None if style == ScalarStyle::Plain => {
1107            return driver.emit_borrowed(resolve_plain_implicit(value, version));
1108        }
1109        None => return driver.emit_borrowed(Atom::Str(value.into())),
1110        Some(tag) => tag,
1111    };
1112    match classify_tag(&tag) {
1113        ScalarTag::Str => driver.emit_borrowed(Atom::Str(value.into())),
1114        ScalarTag::Standard(name) => match resolve_standard(name, value, version) {
1115            Ok(atom) => driver.emit_borrowed(atom),
1116            Err(msg) => Err(error_at(start, msg)),
1117        },
1118        ScalarTag::Custom => emit_tagged(driver, &tag, Atom::Str(value.into())),
1119    }
1120}
1121
1122/// Emits an event with a tag attached to it.
1123#[cold]
1124fn emit_tagged<'a, E: Into<Event<'a>>>(
1125    driver: &mut DeserializeDriver<'_, 'a>,
1126    tag: &str,
1127    event: E,
1128) -> Result<(), Error> {
1129    driver.state_mut().event_mut::<NodeTag>().0 = Some(tag.to_string());
1130    driver.emit_borrowed(event)
1131}
1132
1133fn str_from_utf8(bytes: &[u8]) -> Result<&str, Error> {
1134    #[cfg(feature = "speedups")]
1135    {
1136        if simdutf8::basic::from_utf8(bytes).is_ok() {
1137            // SAFETY: validated above
1138            return Ok(unsafe { std::str::from_utf8_unchecked(bytes) });
1139        }
1140    }
1141    std::str::from_utf8(bytes)
1142        .map_err(|err| Error::with_offset(ErrorKind::Syntax, "invalid UTF-8", err.valid_up_to()))
1143}
1144
1145/// An iterator over the documents of a YAML stream.
1146///
1147/// See [`Deserializer::iter`].
1148pub struct Iter<'b, 'a, T> {
1149    de: &'b mut Deserializer<'a>,
1150    failed: bool,
1151    _marker: PhantomData<fn() -> T>,
1152}
1153
1154impl<'b, 'a, T: Deserialize<'a>> Iterator for Iter<'b, 'a, T> {
1155    type Item = Result<T, Error>;
1156
1157    fn next(&mut self) -> Option<Self::Item> {
1158        if self.failed || self.de.is_end() {
1159            return None;
1160        }
1161        let rv = self.de.deserialize();
1162        self.failed = rv.is_err();
1163        Some(rv)
1164    }
1165}
1166
1167impl<'a> de::Deserializer<'a> for Deserializer<'a> {
1168    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
1169        Deserializer::drive(self, driver)
1170    }
1171}
1172
1173/// Deserializes a value from YAML.
1174///
1175/// The input must contain at most one document.  An empty stream (no
1176/// document at all, for instance an empty file) is deserialized as null.
1177/// This uses the default [`DeserializerConfig`].
1178pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
1179    DeserializerConfig::new().from_str(s)
1180}
1181
1182/// Deserializes a value from YAML in a byte slice.
1183///
1184/// The input must be UTF-8.  Otherwise this works like [`from_str`].  This
1185/// uses the default [`DeserializerConfig`].
1186pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
1187    DeserializerConfig::new().from_slice(bytes)
1188}
1189
1190/// Deserializes the single document of a stream into the sink of a value
1191/// and checks that no other document follows.
1192fn drive_single<'de>(
1193    mut deserializer: Deserializer<'de>,
1194    driver: &mut DeserializeDriver<'_, 'de>,
1195) -> Result<(), Error> {
1196    if deserializer.is_end() {
1197        return de::Deserializer::drive(&mut EmptyDocument, driver);
1198    }
1199    de::Deserializer::drive(&mut deserializer, driver)?;
1200    deserializer.end()
1201}
1202
1203/// The deserializer of an empty document, which is an empty plain scalar.
1204struct EmptyDocument;
1205
1206impl<'de> de::Deserializer<'de> for EmptyDocument {
1207    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'de>) -> Result<(), Error> {
1208        driver.emit(Atom::Implicit(Implicit::new("", ImplicitValue::Null)))
1209    }
1210}