Coverage Report

Created: 2026-10-28 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/rust/registry/src/index.crates.io-1949cf8c6b5b557f/deser-yaml-0.10.1/src/de.rs
Line
Count
Source
1
use std::borrow::Cow;
2
use std::collections::{HashMap, HashSet};
3
use std::marker::PhantomData;
4
use std::sync::Arc;
5
6
use deser_core::de::{self, Deserialize, DeserializeDriver, deserialize_value};
7
use deser_core::hints::Layout;
8
use deser_core::{Atom, Error, ErrorKind, Event, Implicit, ImplicitValue, Source, TrackLocations};
9
10
use crate::event::{Event as YamlEvent, EventKind, Mark, ScalarStyle};
11
use crate::parser::{Parser, error_at};
12
use crate::resolve::{ScalarTag, Version};
13
use crate::resolve::{
14
    classify_tag, is_collection_tag, resolve_plain, resolve_plain_implicit, resolve_standard,
15
};
16
use crate::tag::NodeTag;
17
18
/// The default for [`DeserializerConfig::set_alias_limit`].
19
const 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)]
40
pub struct DeserializerConfig {
41
    version: Version,
42
    alias_limit: usize,
43
    merge_keys: bool,
44
45
    context: deser_core::Context,
46
}
47
48
impl Default for DeserializerConfig {
49
0
    fn default() -> DeserializerConfig {
50
0
        DeserializerConfig::new()
51
0
    }
52
}
53
54
impl DeserializerConfig {
55
    /// Creates the default configuration.
56
37.6k
    pub const fn new() -> DeserializerConfig {
57
37.6k
        DeserializerConfig {
58
37.6k
            version: Version::V1_2,
59
37.6k
            alias_limit: DEFAULT_ALIAS_LIMIT,
60
37.6k
            merge_keys: true,
61
37.6k
62
37.6k
            context: deser_core::Context::new(),
63
37.6k
        }
64
37.6k
    }
65
66
    /// Returns a builder for the configuration (see [`DeserializerConfigBuilder`]).
67
0
    pub const fn builder() -> DeserializerConfigBuilder {
68
0
        DeserializerConfigBuilder::new()
69
0
    }
70
71
    /// Returns a builder that starts with this configuration.
72
0
    pub const fn into_builder(self) -> DeserializerConfigBuilder {
73
0
        DeserializerConfigBuilder { value: self }
74
0
    }
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
0
    pub fn set_context(&mut self, context: deser_core::Context) {
84
0
        self.context = context;
85
0
    }
86
87
    /// Returns the configuration without its context (for the frames of
88
    /// streams, which get the context of the stream).
89
0
    pub(crate) fn without_context(&self) -> DeserializerConfig {
90
0
        let mut config = self.clone();
91
0
        config.context = deser_core::Context::default();
92
0
        config
93
0
    }
94
95
    /// Returns the context the values are deserialized in.
96
0
    pub fn context(&self) -> &deser_core::Context {
97
0
        &self.context
98
0
    }
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
0
    pub const fn set_version(&mut self, version: Version) {
106
0
        self.version = version;
107
0
    }
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
0
    pub const fn set_alias_limit(&mut self, limit: usize) {
114
0
        self.alias_limit = limit;
115
0
    }
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
0
    pub const fn set_merge_keys(&mut self, yes: bool) {
153
0
        self.merge_keys = yes;
154
0
    }
155
156
    /// Deserializes a value from YAML.
157
    ///
158
    /// See [`from_str`].
159
25.1k
    pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
160
25.1k
        deserialize_value(|driver| self.drive_str(s, driver))
<deser_yaml::de::DeserializerConfig>::from_str::<deser_value::value::Value>::{closure#0}
Line
Count
Source
160
25.1k
        deserialize_value(|driver| self.drive_str(s, driver))
Unexecuted instantiation: <deser_yaml::de::DeserializerConfig>::from_str::<_>::{closure#0}
161
25.1k
    }
<deser_yaml::de::DeserializerConfig>::from_str::<deser_value::value::Value>
Line
Count
Source
159
25.1k
    pub fn from_str<'de, T: Deserialize<'de>>(&self, s: &'de str) -> Result<T, Error> {
160
25.1k
        deserialize_value(|driver| self.drive_str(s, driver))
161
25.1k
    }
Unexecuted instantiation: <deser_yaml::de::DeserializerConfig>::from_str::<_>
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
25.1k
    fn drive_str<'de>(
166
25.1k
        &self,
167
25.1k
        s: &'de str,
168
25.1k
        driver: &mut DeserializeDriver<'_, 'de>,
169
25.1k
    ) -> Result<(), Error> {
170
25.1k
        drive_single(Deserializer::from_str_with_config(s, self.clone()), driver)
171
25.1k
    }
172
173
    /// Deserializes a value from YAML in a byte slice.
174
    ///
175
    /// See [`from_slice`].
176
0
    pub fn from_slice<'de, T: Deserialize<'de>>(&self, bytes: &'de [u8]) -> Result<T, Error> {
177
0
        deserialize_value(|driver| self.drive_slice(bytes, driver))
178
0
    }
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
0
    fn drive_slice<'de>(
183
0
        &self,
184
0
        bytes: &'de [u8],
185
0
        driver: &mut DeserializeDriver<'_, 'de>,
186
0
    ) -> Result<(), Error> {
187
0
        drive_single(
188
0
            Deserializer::from_slice_with_config(bytes, self.clone()),
189
0
            driver,
190
        )
191
0
    }
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]
199
pub struct DeserializerConfigBuilder {
200
    value: DeserializerConfig,
201
}
202
203
impl DeserializerConfigBuilder {
204
    /// Creates a builder that starts with the default.
205
0
    pub const fn new() -> DeserializerConfigBuilder {
206
0
        DeserializerConfigBuilder {
207
0
            value: DeserializerConfig::new(),
208
0
        }
209
0
    }
210
211
    /// Sets the YAML version for documents that do not declare one.
212
    ///
213
    /// See [`DeserializerConfig::set_version`].
214
0
    pub const fn version(mut self, version: Version) -> DeserializerConfigBuilder {
215
0
        self.value.set_version(version);
216
0
        self
217
0
    }
218
219
    /// Limits the number of events that aliases can expand to per document.
220
    ///
221
    /// See [`DeserializerConfig::set_alias_limit`].
222
0
    pub const fn alias_limit(mut self, limit: usize) -> DeserializerConfigBuilder {
223
0
        self.value.set_alias_limit(limit);
224
0
        self
225
0
    }
226
227
    /// Enables or disables merge keys.
228
    ///
229
    /// See [`DeserializerConfig::set_merge_keys`].
230
0
    pub const fn merge_keys(mut self, yes: bool) -> DeserializerConfigBuilder {
231
0
        self.value.set_merge_keys(yes);
232
0
        self
233
0
    }
234
235
    /// Sets the context the values are deserialized in.
236
    ///
237
    /// See [`DeserializerConfig::set_context`].
238
0
    pub fn context(mut self, context: deser_core::Context) -> DeserializerConfigBuilder {
239
0
        self.value.set_context(context);
240
0
        self
241
0
    }
242
243
    /// Returns the built [`DeserializerConfig`].
244
0
    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
0
        let value = unsafe { core::ptr::read(&self.value) };
249
0
        core::mem::forget(self);
250
0
        value
251
0
    }
252
}
253
254
impl Default for DeserializerConfigBuilder {
255
0
    fn default() -> DeserializerConfigBuilder {
256
0
        DeserializerConfigBuilder::new()
257
0
    }
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`].
284
pub 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)]
304
enum 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)]
332
struct 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.
349
struct 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
359
impl<'a> Document<'a> {
360
135k
    fn reset(&mut self, version: Version) {
361
135k
        self.version = version;
362
135k
        self.nodes.clear();
363
135k
        self.anchors.clear();
364
135k
        self.open.clear();
365
135k
        self.captured = None;
366
135k
        self.depth = 0;
367
135k
    }
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
14.1M
    fn record(&mut self, event: YamlEvent<'a>, capture: bool) -> Result<Node<'a>, Error> {
374
14.1M
        let start = event.start;
375
14.1M
        let end = event.end.offset;
376
14.1M
        let is_map = matches!(event.kind, EventKind::MappingStart { .. });
377
14.1M
        let (node, anchor) = match event.kind {
378
            EventKind::Scalar {
379
7.06M
                props,
380
7.06M
                style,
381
7.06M
                value,
382
7.06M
            } => (
383
7.06M
                Node::Scalar {
384
7.06M
                    tag: props.tag,
385
7.06M
                    style,
386
7.06M
                    value,
387
7.06M
                    start,
388
7.06M
                    end,
389
7.06M
                },
390
7.06M
                props.anchor,
391
7.06M
            ),
392
2.87M
            EventKind::SequenceStart { props, flow } | EventKind::MappingStart { props, flow } => {
393
4.60M
                self.depth += 1;
394
4.60M
                (
395
4.60M
                    Node::Start {
396
4.60M
                        tag: props.tag,
397
4.60M
                        is_map,
398
4.60M
                        flow,
399
4.60M
                        start,
400
4.60M
                        end,
401
4.60M
                    },
402
4.60M
                    props.anchor,
403
4.60M
                )
404
            }
405
            EventKind::SequenceEnd | EventKind::MappingEnd => {
406
2.44M
                let is_map = event.kind == EventKind::MappingEnd;
407
2.44M
                self.depth -= 1;
408
2.44M
                let node = Node::End { is_map, start, end };
409
2.44M
                if !self.open.is_empty() {
410
410k
                    self.nodes.push(node.clone());
411
410k
                    let depth = self.depth + 1;
412
410k
                    if let Some(open) = self.open.pop_if(|x| x.depth == depth) {
413
62.9k
                        let range = (open.start, self.nodes.len());
414
62.9k
                        if let Some(name) = open.anchor {
415
41.3k
                            self.anchors.insert(name, range);
416
41.3k
                        }
417
62.9k
                        if open.capture {
418
22.0k
                            self.captured = Some(range);
419
40.8k
                        }
420
347k
                    }
421
2.03M
                }
422
2.44M
                return Ok(node);
423
            }
424
14.5k
            EventKind::Alias { anchor } => {
425
2.42M
                if self.open.iter().any(|x| x.anchor.as_ref() == Some(&anchor)) {
426
19
                    return Err(error_at(start, "recursive alias"));
427
14.5k
                }
428
14.5k
                let range = match self.anchors.get(&anchor) {
429
14.0k
                    Some(&range) => range,
430
476
                    None => return Err(error_at(start, &format!("unknown anchor `{}`", anchor))),
431
                };
432
14.0k
                let node = Node::Alias { range };
433
14.0k
                if !self.open.is_empty() {
434
13.0k
                    self.nodes.push(node.clone());
435
13.0k
                }
436
14.0k
                return Ok(node);
437
            }
438
0
            _ => unreachable!("unexpected event in document"),
439
        };
440
441
11.6M
        let is_start = matches!(node, Node::Start { .. });
442
11.6M
        if anchor.is_some() || (capture && is_start) || !self.open.is_empty() {
443
3.23M
            let index = self.nodes.len();
444
3.23M
            self.nodes.push(node.clone());
445
3.23M
            if is_start && (anchor.is_some() || capture) {
446
143k
                self.open.push(OpenNode {
447
143k
                    anchor,
448
143k
                    start: index,
449
143k
                    depth: self.depth,
450
143k
                    capture,
451
143k
                });
452
3.08M
            } else if let Some(name) = anchor {
453
188k
                self.anchors.insert(name, (index, index + 1));
454
2.89M
            }
455
8.44M
        }
456
11.6M
        Ok(node)
457
14.1M
    }
458
459
    /// Returns the index after the recorded node that starts at `index`.
460
190k
    fn node_end(&self, index: usize) -> usize {
461
190k
        if !matches!(self.nodes[index], Node::Start { .. }) {
462
137k
            return index + 1;
463
52.5k
        }
464
52.5k
        let mut depth = 0;
465
1.38M
        for (offset, node) in self.nodes[index..].iter().enumerate() {
466
1.38M
            match node {
467
268k
                Node::Start { .. } => depth += 1,
468
                Node::End { .. } => {
469
268k
                    depth -= 1;
470
268k
                    if depth == 0 {
471
52.5k
                        return index + offset + 1;
472
215k
                    }
473
                }
474
852k
                _ => {}
475
            }
476
        }
477
0
        unreachable!("unbalanced recording");
478
190k
    }
479
480
    /// Follows a recorded alias to the range of the node it refers to.
481
135k
    fn resolve_range(&self, mut range: (usize, usize)) -> (usize, usize) {
482
135k
        while let Node::Alias { range: target } = self.nodes[range.0] {
483
0
            range = target;
484
0
        }
485
135k
        range
486
135k
    }
487
488
    /// Returns the ranges of the items of a recorded collection.
489
45.3k
    fn items(&self, range: (usize, usize)) -> impl Iterator<Item = (usize, usize)> + '_ {
490
45.3k
        let mut index = range.0 + 1;
491
265k
        std::iter::from_fn(move || {
492
265k
            if index + 1 >= range.1 {
493
77.0k
                return None;
494
188k
            }
495
188k
            let item = (index, self.node_end(index));
496
188k
            index = item.1;
497
188k
            Some(item)
498
265k
        })
499
45.3k
    }
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)]
507
enum 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
518
impl<'a> KeyId<'a> {
519
2.36M
    fn of_scalar(
520
2.36M
        tag: &Option<Cow<'a, str>>,
521
2.36M
        style: ScalarStyle,
522
2.36M
        value: &Cow<'a, str>,
523
2.36M
        version: Version,
524
2.36M
    ) -> Option<KeyId<'a>> {
525
2.22M
        let atom = match tag {
526
2.22M
            None if style == ScalarStyle::Plain => resolve_plain(value.clone(), version),
527
464k
            None => return Some(KeyId::Str(value.clone())),
528
139k
            Some(tag) => match classify_tag(tag) {
529
9.98k
                ScalarTag::Str => return Some(KeyId::Str(value.clone())),
530
5.93k
                ScalarTag::Standard(name) => resolve_standard(name, value.clone(), version).ok()?,
531
123k
                ScalarTag::Custom => return Some(KeyId::Tagged(tag.clone(), value.clone())),
532
            },
533
        };
534
1.76M
        Some(match atom {
535
255k
            Atom::Null => KeyId::Null,
536
7.52k
            Atom::Bool(value) => KeyId::Bool(value),
537
35.4k
            Atom::U64(value) => KeyId::Int(false, value.into()),
538
24.4k
            Atom::I64(value) => KeyId::Int(value < 0, value.unsigned_abs().into()),
539
32.2k
            Atom::F64(value) => KeyId::Float(value.to_bits()),
540
1.39M
            Atom::Str(value) => KeyId::Str(value.into_cow()),
541
2.30k
            Atom::Bytes(value) => KeyId::Bytes(value.into_owned()),
542
17.8k
            Atom::Ext(ref ext) => {
543
17.8k
                if let Some(&value) = ext.downcast_ref::<u128>() {
544
2.57k
                    KeyId::Int(false, value)
545
15.3k
                } else if let Some(&value) = ext.downcast_ref::<i128>() {
546
15.3k
                    KeyId::Int(value < 0, value.unsigned_abs())
547
                } else {
548
0
                    return None;
549
                }
550
            }
551
0
            _ => return None,
552
        })
553
2.36M
    }
554
}
555
556
2.39M
fn is_merge_key(tag: &Option<Cow<'_, str>>, style: ScalarStyle, value: &str) -> bool {
557
2.39M
    tag.is_none() && style == ScalarStyle::Plain && value == "<<"
558
2.39M
}
559
560
/// Something that is emitted before the next event from the parser.
561
enum 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.
569
struct 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
579
impl<'a> Deserializer<'a> {
580
    /// Creates a new deserializer for a string.
581
    #[allow(clippy::should_implement_trait)]
582
12.5k
    pub fn from_str(input: &'a str) -> Deserializer<'a> {
583
12.5k
        Deserializer::from_str_with_config(input, DeserializerConfig::new())
584
12.5k
    }
585
586
    /// Creates a new deserializer for a string with the given configuration.
587
37.6k
    pub fn from_str_with_config(input: &'a str, config: DeserializerConfig) -> Deserializer<'a> {
588
37.6k
        let track_merges = config.merge_keys && input.contains("<<");
589
37.6k
        Deserializer {
590
37.6k
            input,
591
37.6k
            parser: Parser::new(input),
592
37.6k
            peeked: None,
593
37.6k
            started: false,
594
37.6k
            pending_error: None,
595
37.6k
            failed: false,
596
37.6k
            config,
597
37.6k
            track_merges,
598
37.6k
            source: None,
599
37.6k
            doc: Document::default(),
600
37.6k
        }
601
37.6k
    }
602
603
    /// Creates a new deserializer for a byte slice.
604
    ///
605
    /// The input must be UTF-8, otherwise deserializing fails.
606
0
    pub fn from_slice(input: &'a [u8]) -> Deserializer<'a> {
607
0
        Deserializer::from_slice_with_config(input, DeserializerConfig::new())
608
0
    }
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
0
    pub fn from_slice_with_config(input: &'a [u8], config: DeserializerConfig) -> Deserializer<'a> {
615
0
        match str_from_utf8(input) {
616
0
            Ok(input) => Deserializer::from_str_with_config(input, config),
617
0
            Err(err) => {
618
0
                let mut rv = Deserializer::from_str_with_config("", config);
619
0
                rv.pending_error = Some(err);
620
0
                rv.failed = true;
621
0
                rv
622
            }
623
        }
624
0
    }
625
626
    /// Returns the configuration.
627
0
    pub fn config(&self) -> &DeserializerConfig {
628
0
        &self.config
629
0
    }
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
160k
    pub fn is_end(&mut self) -> bool {
636
160k
        if self.failed {
637
0
            return self.pending_error.is_none();
638
160k
        }
639
160k
        match self.peek_event() {
640
157k
            Ok(event) => event.kind == EventKind::StreamEnd,
641
2.84k
            Err(err) => {
642
2.84k
                self.pending_error = Some(err);
643
2.84k
                false
644
            }
645
        }
646
160k
    }
647
648
    /// Fails if there are more documents.
649
15.3k
    pub fn end(&mut self) -> Result<(), Error> {
650
15.3k
        if self.is_end() {
651
11.0k
            Ok(())
652
4.26k
        } else if let Some(err) = self.pending_error.take() {
653
16
            Err(err)
654
        } else {
655
4.24k
            Err(Error::new(
656
4.24k
                ErrorKind::Syntax,
657
4.24k
                "expected a single document, found more",
658
4.24k
            ))
659
        }
660
15.3k
    }
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
113k
    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
672
113k
        de::Deserializer::deserialize(self)
673
113k
    }
<deser_yaml::de::Deserializer>::deserialize::<deser_value::value::Value>
Line
Count
Source
671
113k
    pub fn deserialize<T: Deserialize<'a>>(&mut self) -> Result<T, Error> {
672
113k
        de::Deserializer::deserialize(self)
673
113k
    }
Unexecuted instantiation: <deser_yaml::de::Deserializer>::deserialize::<_>
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
0
    pub fn deserialize_with<T, F>(&mut self, setup: F) -> Result<T, Error>
680
0
    where
681
0
        T: Deserialize<'a>,
682
0
        F: FnOnce(&mut DeserializeDriver<'_, 'a>),
683
    {
684
0
        de::Deserializer::deserialize_with(self, setup)
685
0
    }
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
12.5k
    pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
697
12.5k
        Iter {
698
12.5k
            de: self,
699
12.5k
            failed: false,
700
12.5k
            _marker: PhantomData,
701
12.5k
        }
702
12.5k
    }
<deser_yaml::de::Deserializer>::iter::<deser_value::value::Value>
Line
Count
Source
696
12.5k
    pub fn iter<T: Deserialize<'a>>(&mut self) -> Iter<'_, 'a, T> {
697
12.5k
        Iter {
698
12.5k
            de: self,
699
12.5k
            failed: false,
700
12.5k
            _marker: PhantomData,
701
12.5k
        }
702
12.5k
    }
Unexecuted instantiation: <deser_yaml::de::Deserializer>::iter::<_>
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
138k
    pub fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
714
138k
        if !self.config.context.is_empty() {
715
0
            driver.set_default_context(self.config.context.clone());
716
138k
        }
717
138k
        if let Some(err) = self.pending_error.take() {
718
2.83k
            return Err(err);
719
135k
        }
720
135k
        if self.failed {
721
0
            return Err(Error::new(
722
0
                ErrorKind::InvalidState,
723
0
                "cannot continue after a syntax error",
724
0
            ));
725
135k
        }
726
727
135k
        let event = self.next_event()?;
728
135k
        let version = match event.kind {
729
135k
            EventKind::DocumentStart { version, .. } => match version {
730
0
                Some((1, minor)) if minor < 2 => Version::V1_1,
731
0
                Some(_) => Version::V1_2,
732
135k
                None => self.config.version,
733
            },
734
            EventKind::StreamEnd => {
735
                // stay at the end of the stream
736
0
                self.peeked = Some(event);
737
0
                return Err(Error::new(ErrorKind::EndOfFile, "no more documents"));
738
            }
739
0
            _ => unreachable!("expected document start"),
740
        };
741
135k
        self.doc.reset(version);
742
743
135k
        if TrackLocations::of(driver.state()) {
744
0
            let source = self.source.get_or_insert_with(|| self.input.into());
745
0
            Source(source.clone()).set(driver.state_mut());
746
135k
        }
747
135k
        let input = self.input;
748
135k
        let rv = self.drive_document(driver).map_err(|mut err| {
749
13.1k
            err.resolve_position(input.as_bytes());
750
13.1k
            err
751
13.1k
        });
752
753
135k
        if rv.is_err() && !self.failed {
754
            // skip the rest of the document so that the next one can be read
755
3.72k
            if let Err(err) = self.skip_document() {
756
2.52k
                self.pending_error = Some(err);
757
2.52k
            }
758
131k
        }
759
135k
        rv
760
138k
    }
761
762
15.2M
    fn ensure_started(&mut self) -> Result<(), Error> {
763
15.2M
        if !self.started {
764
37.6k
            self.started = true;
765
37.6k
            let event = self.parser_event()?;
766
37.6k
            debug_assert_eq!(event.kind, EventKind::StreamStart);
767
15.1M
        }
768
15.2M
        Ok(())
769
15.2M
    }
770
771
15.1M
    fn parser_event(&mut self) -> Result<YamlEvent<'a>, Error> {
772
15.1M
        self.parser.next_event().inspect_err(|_| {
773
14.7k
            self.failed = true;
774
14.7k
        })
775
15.1M
    }
776
777
15.2M
    fn next_event(&mut self) -> Result<YamlEvent<'a>, Error> {
778
15.2M
        self.ensure_started()?;
779
15.2M
        match self.peeked.take() {
780
135k
            Some(event) => Ok(event),
781
15.1M
            None => self.parser_event(),
782
        }
783
15.2M
    }
784
785
160k
    fn peek_event(&mut self) -> Result<&YamlEvent<'a>, Error> {
786
160k
        if self.peeked.is_none() {
787
160k
            let event = self.next_event()?;
788
157k
            self.peeked = Some(event);
789
0
        }
790
157k
        Ok(self.peeked.as_ref().unwrap())
791
160k
    }
792
793
3.72k
    fn skip_document(&mut self) -> Result<(), Error> {
794
        loop {
795
679k
            if let EventKind::DocumentEnd { .. } = self.next_event()?.kind {
796
1.20k
                return Ok(());
797
675k
            }
798
        }
799
3.72k
    }
800
801
135k
    fn drive_document(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
802
        // nodes that are emitted before the next event from the parser
803
135k
        let mut pending: Vec<Pending<'a>> = Vec::new();
804
        // the number of nodes produced by aliases and merges
805
135k
        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
135k
        let track_merges = self.track_merges;
809
135k
        let mut frames: Vec<Frame<'a>> = Vec::new();
810
135k
        let mut merge_value_follows = false;
811
812
        loop {
813
13.6M
            let (node, index) =
814
13.8M
                match self.next_node(&mut pending, &mut replayed, merge_value_follows)? {
815
13.6M
                    Some(rv) => rv,
816
122k
                    None => return Ok(()),
817
                };
818
819
13.6M
            if merge_value_follows {
820
24.3k
                merge_value_follows = false;
821
24.3k
                let range = self.merge_source(node, index, &mut pending)?;
822
24.0k
                let frame = frames.last_mut().unwrap();
823
24.0k
                frame.sources.push(range);
824
24.0k
                frame.expect_key = true;
825
24.0k
                continue;
826
13.6M
            }
827
828
13.6M
            if track_merges
829
7.65M
                && let Some(frame) = frames.last_mut()
830
7.63M
                && frame.is_map
831
            {
832
6.05M
                if frame.expect_key
833
                    && let Node::Scalar {
834
2.31M
                        ref tag,
835
2.31M
                        style,
836
2.31M
                        ref value,
837
                        ..
838
3.62M
                    } = node
839
                {
840
2.31M
                    if is_merge_key(tag, style, value) {
841
24.3k
                        frame.expect_key = false;
842
24.3k
                        merge_value_follows = true;
843
24.3k
                        continue;
844
2.29M
                    }
845
2.29M
                    if let Some(id) = KeyId::of_scalar(tag, style, value, self.doc.version) {
846
2.29M
                        frame.keys.insert(id);
847
2.29M
                    }
848
3.73M
                }
849
                // aliases are replayed, their nodes are counted
850
6.02M
                if !matches!(node, Node::Alias { .. } | Node::End { .. }) {
851
5.55M
                    frame.expect_key = !frame.expect_key;
852
5.55M
                }
853
7.60M
            }
854
855
13.6M
            match node {
856
                Node::Scalar {
857
6.81M
                    tag,
858
6.81M
                    style,
859
6.81M
                    value,
860
6.81M
                    start,
861
6.81M
                    end,
862
                } => {
863
6.81M
                    let version = self.doc.version;
864
6.81M
                    emit_scalar(driver, tag, style, value, version, start, end)?;
865
                }
866
                Node::Start {
867
4.48M
                    tag,
868
4.48M
                    is_map,
869
4.48M
                    flow,
870
4.48M
                    start,
871
4.48M
                    end,
872
                } => {
873
                    // flow collections are compact so that they stay flow
874
                    // collections when they are serialized again
875
4.48M
                    if flow {
876
2.54M
                        Layout::Compact.set(driver.state_mut());
877
2.54M
                    }
878
4.48M
                    if track_merges {
879
2.51M
                        frames.push(Frame {
880
2.51M
                            is_map,
881
2.51M
                            expect_key: true,
882
2.51M
                            keys: HashSet::new(),
883
2.51M
                            sources: Vec::new(),
884
2.51M
                        });
885
2.51M
                    }
886
4.48M
                    let event = if is_map {
887
2.78M
                        Event::map_start()
888
                    } else {
889
1.69M
                        Event::seq_start()
890
                    };
891
4.48M
                    driver.state_mut().set_input_range(start.offset, end);
892
4.48M
                    match tag {
893
80.6k
                        Some(tag) => match is_collection_tag(&tag, is_map) {
894
21.2k
                            Ok(true) => driver.emit(event)?,
895
59.3k
                            Ok(false) => emit_tagged(driver, &tag, event)?,
896
28
                            Err(msg) => return Err(error_at(start, msg)),
897
                        },
898
4.40M
                        None => driver.emit(event)?,
899
                    }
900
                }
901
2.32M
                Node::End { is_map, start, end } => {
902
2.32M
                    if track_merges {
903
577k
                        let frame = frames.last_mut().unwrap();
904
577k
                        if !frame.sources.is_empty() {
905
                            // emit the merged entries before the end of the
906
                            // map, the end is emitted again afterwards
907
3.13k
                            let sources = std::mem::take(&mut frame.sources);
908
2.93k
                            let entries =
909
3.13k
                                self.merged_entries(&sources, &mut frame.keys, &mut replayed)?;
910
2.93k
                            pending.push(Pending::Node(Node::End { is_map, start, end }));
911
27.3k
                            for (key, value) in entries.into_iter().rev() {
912
27.3k
                                pending.push(Pending::Range(value.0, value.1));
913
27.3k
                                pending.push(Pending::Range(key.0, key.1));
914
27.3k
                            }
915
2.93k
                            continue;
916
574k
                        }
917
574k
                        frames.pop();
918
1.74M
                    }
919
2.32M
                    let event = if is_map { Event::MapEnd } else { Event::SeqEnd };
920
2.32M
                    driver.state_mut().set_input_range(start.offset, end);
921
2.32M
                    driver.emit(event)?;
922
                }
923
13.8k
                Node::Alias { range } => pending.push(Pending::Range(range.0, range.1)),
924
            }
925
        }
926
135k
    }
927
928
    /// Returns the next node and its index if it was recorded.  Returns
929
    /// `None` at the end of the document.
930
13.8M
    fn next_node(
931
13.8M
        &mut self,
932
13.8M
        pending: &mut Vec<Pending<'a>>,
933
13.8M
        replayed: &mut usize,
934
13.8M
        capture: bool,
935
13.8M
    ) -> Result<Option<(Node<'a>, Option<usize>)>, Error> {
936
        loop {
937
13.8M
            let (node, index) = match pending.last_mut() {
938
298k
                Some(Pending::Range(start, end)) => {
939
298k
                    if start == end {
940
60.4k
                        pending.pop();
941
60.4k
                        continue;
942
237k
                    }
943
237k
                    let index = *start;
944
237k
                    *start += 1;
945
237k
                    (self.doc.nodes[index].clone(), Some(index))
946
                }
947
2.51k
                Some(Pending::Node(_)) => match pending.pop() {
948
2.51k
                    Some(Pending::Node(node)) => return Ok(Some((node, None))),
949
0
                    _ => unreachable!(),
950
                },
951
                None => {
952
13.5M
                    let event = self.next_event()?;
953
13.5M
                    if let EventKind::DocumentEnd { .. } = event.kind {
954
122k
                        return Ok(None);
955
13.4M
                    }
956
13.4M
                    return Ok(Some((self.doc.record(event, capture)?, None)));
957
                }
958
            };
959
237k
            self.count_replayed(replayed, 1)?;
960
237k
            return Ok(Some((node, index)));
961
        }
962
13.8M
    }
963
964
269k
    fn count_replayed(&self, replayed: &mut usize, count: usize) -> Result<(), Error> {
965
269k
        *replayed += count;
966
269k
        if *replayed > self.config.alias_limit {
967
0
            Err(Error::new(
968
0
                ErrorKind::LimitExceeded,
969
0
                "aliases expand to too many events",
970
0
            ))
971
        } else {
972
269k
            Ok(())
973
        }
974
269k
    }
975
976
    /// Consumes the value of a merge key and returns the range of its
977
    /// recorded nodes.
978
24.3k
    fn merge_source(
979
24.3k
        &mut self,
980
24.3k
        node: Node<'a>,
981
24.3k
        index: Option<usize>,
982
24.3k
        pending: &mut [Pending<'a>],
983
24.3k
    ) -> Result<(usize, usize), Error> {
984
24.3k
        match node {
985
0
            Node::Alias { range } => Ok(range),
986
24.2k
            Node::Start { .. } => match index {
987
                // the value is replayed, skip it
988
1.99k
                Some(index) => {
989
1.99k
                    let end = self.doc.node_end(index);
990
1.99k
                    if let Some(Pending::Range(start, _)) = pending.last_mut() {
991
1.99k
                        *start = end;
992
1.99k
                    }
993
1.99k
                    Ok((index, end))
994
                }
995
                // the value comes from the parser, record it without
996
                // emitting it
997
                None => {
998
707k
                    while self.doc.captured.is_none() {
999
685k
                        let event = self.next_event()?;
1000
685k
                        self.doc.record(event, false)?;
1001
                    }
1002
22.0k
                    Ok(self.doc.captured.take().unwrap())
1003
                }
1004
            },
1005
63
            Node::Scalar { start, .. } | Node::End { start, .. } => Err(error_at(
1006
63
                start,
1007
63
                "the value of a merge key must be a mapping or a sequence of mappings",
1008
63
            )),
1009
        }
1010
24.3k
    }
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
3.13k
    fn merged_entries(
1019
3.13k
        &self,
1020
3.13k
        sources: &[(usize, usize)],
1021
3.13k
        keys: &mut HashSet<KeyId<'a>>,
1022
3.13k
        replayed: &mut usize,
1023
3.13k
    ) -> Result<Vec<((usize, usize), (usize, usize))>, Error> {
1024
3.13k
        let mut entries = Vec::new();
1025
        // the mappings to merge in reverse order
1026
3.13k
        let mut stack = Vec::new();
1027
3.13k
        self.push_merge_sources(sources, &mut stack);
1028
1029
34.8k
        while let Some(range) = stack.pop() {
1030
31.9k
            match self.doc.nodes[range.0] {
1031
31.7k
                Node::Start { is_map: true, .. } => {}
1032
168
                Node::Start { start, .. } | Node::Scalar { start, .. } => {
1033
203
                    return Err(error_at(
1034
203
                        start,
1035
203
                        "merge keys can only merge mappings or sequences of mappings",
1036
203
                    ));
1037
                }
1038
0
                _ => unreachable!(),
1039
            }
1040
31.7k
            self.count_replayed(replayed, range.1 - range.0)?;
1041
1042
31.7k
            let mut nested = Vec::new();
1043
31.7k
            let mut items = self.doc.items(range);
1044
110k
            while let (Some(key), Some(value)) = (items.next(), items.next()) {
1045
                if let Node::Scalar {
1046
77.1k
                    tag: ref key_tag,
1047
77.1k
                    style,
1048
77.1k
                    value: ref key_value,
1049
                    ..
1050
78.6k
                } = self.doc.nodes[self.doc.resolve_range(key).0]
1051
                {
1052
77.1k
                    if is_merge_key(key_tag, style, key_value) {
1053
2.63k
                        nested.push(value);
1054
2.63k
                        continue;
1055
74.5k
                    }
1056
74.5k
                    let version = self.doc.version;
1057
74.5k
                    if let Some(id) = KeyId::of_scalar(key_tag, style, key_value, version)
1058
72.7k
                        && !keys.insert(id)
1059
                    {
1060
                        // the map (or an earlier source) has the key
1061
47.9k
                        continue;
1062
26.6k
                    }
1063
1.51k
                }
1064
28.1k
                entries.push((key, value));
1065
            }
1066
31.7k
            self.push_merge_sources(&nested, &mut stack);
1067
        }
1068
2.93k
        Ok(entries)
1069
3.13k
    }
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
34.8k
    fn push_merge_sources(&self, sources: &[(usize, usize)], stack: &mut Vec<(usize, usize)>) {
1074
34.8k
        for &source in sources.iter().rev() {
1075
26.0k
            let source = self.doc.resolve_range(source);
1076
26.0k
            match self.doc.nodes[source.0] {
1077
                Node::Start { is_map: false, .. } => {
1078
13.6k
                    let items: Vec<_> = self
1079
13.6k
                        .doc
1080
13.6k
                        .items(source)
1081
31.0k
                        .map(|item| self.doc.resolve_range(item))
1082
13.6k
                        .collect();
1083
13.6k
                    stack.extend(items.into_iter().rev());
1084
                }
1085
12.4k
                _ => stack.push(source),
1086
            }
1087
        }
1088
34.8k
    }
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.
1095
6.81M
fn emit_scalar<'a>(
1096
6.81M
    driver: &mut DeserializeDriver<'_, 'a>,
1097
6.81M
    tag: Option<Cow<'_, str>>,
1098
6.81M
    style: ScalarStyle,
1099
6.81M
    value: Cow<'a, str>,
1100
6.81M
    version: Version,
1101
6.81M
    start: Mark,
1102
6.81M
    end: usize,
1103
6.81M
) -> Result<(), Error> {
1104
6.81M
    driver.state_mut().set_input_range(start.offset, end);
1105
6.60M
    let tag = match tag {
1106
6.60M
        None if style == ScalarStyle::Plain => {
1107
5.92M
            return driver.emit_borrowed(resolve_plain_implicit(value, version));
1108
        }
1109
682k
        None => return driver.emit_borrowed(Atom::Str(value.into())),
1110
204k
        Some(tag) => tag,
1111
    };
1112
204k
    match classify_tag(&tag) {
1113
28.3k
        ScalarTag::Str => driver.emit_borrowed(Atom::Str(value.into())),
1114
6.33k
        ScalarTag::Standard(name) => match resolve_standard(name, value, version) {
1115
5.47k
            Ok(atom) => driver.emit_borrowed(atom),
1116
862
            Err(msg) => Err(error_at(start, msg)),
1117
        },
1118
169k
        ScalarTag::Custom => emit_tagged(driver, &tag, Atom::Str(value.into())),
1119
    }
1120
6.81M
}
1121
1122
/// Emits an event with a tag attached to it.
1123
#[cold]
1124
228k
fn emit_tagged<'a, E: Into<Event<'a>>>(
1125
228k
    driver: &mut DeserializeDriver<'_, 'a>,
1126
228k
    tag: &str,
1127
228k
    event: E,
1128
228k
) -> Result<(), Error> {
1129
228k
    driver.state_mut().event_mut::<NodeTag>().0 = Some(tag.to_string());
1130
228k
    driver.emit_borrowed(event)
1131
228k
}
deser_yaml::de::emit_tagged::<deser_core::event::Atom>
Line
Count
Source
1124
169k
fn emit_tagged<'a, E: Into<Event<'a>>>(
1125
169k
    driver: &mut DeserializeDriver<'_, 'a>,
1126
169k
    tag: &str,
1127
169k
    event: E,
1128
169k
) -> Result<(), Error> {
1129
169k
    driver.state_mut().event_mut::<NodeTag>().0 = Some(tag.to_string());
1130
169k
    driver.emit_borrowed(event)
1131
169k
}
deser_yaml::de::emit_tagged::<deser_core::event::Event>
Line
Count
Source
1124
59.3k
fn emit_tagged<'a, E: Into<Event<'a>>>(
1125
59.3k
    driver: &mut DeserializeDriver<'_, 'a>,
1126
59.3k
    tag: &str,
1127
59.3k
    event: E,
1128
59.3k
) -> Result<(), Error> {
1129
59.3k
    driver.state_mut().event_mut::<NodeTag>().0 = Some(tag.to_string());
1130
59.3k
    driver.emit_borrowed(event)
1131
59.3k
}
1132
1133
0
fn str_from_utf8(bytes: &[u8]) -> Result<&str, Error> {
1134
    #[cfg(feature = "speedups")]
1135
    {
1136
0
        if simdutf8::basic::from_utf8(bytes).is_ok() {
1137
            // SAFETY: validated above
1138
0
            return Ok(unsafe { std::str::from_utf8_unchecked(bytes) });
1139
0
        }
1140
    }
1141
0
    std::str::from_utf8(bytes)
1142
0
        .map_err(|err| Error::with_offset(ErrorKind::Syntax, "invalid UTF-8", err.valid_up_to()))
1143
0
}
1144
1145
/// An iterator over the documents of a YAML stream.
1146
///
1147
/// See [`Deserializer::iter`].
1148
pub struct Iter<'b, 'a, T> {
1149
    de: &'b mut Deserializer<'a>,
1150
    failed: bool,
1151
    _marker: PhantomData<fn() -> T>,
1152
}
1153
1154
impl<'b, 'a, T: Deserialize<'a>> Iterator for Iter<'b, 'a, T> {
1155
    type Item = Result<T, Error>;
1156
1157
119k
    fn next(&mut self) -> Option<Self::Item> {
1158
119k
        if self.failed || self.de.is_end() {
1159
6.22k
            return None;
1160
113k
        }
1161
113k
        let rv = self.de.deserialize();
1162
113k
        self.failed = rv.is_err();
1163
113k
        Some(rv)
1164
119k
    }
<deser_yaml::de::Iter<deser_value::value::Value> as core::iter::traits::iterator::Iterator>::next
Line
Count
Source
1157
119k
    fn next(&mut self) -> Option<Self::Item> {
1158
119k
        if self.failed || self.de.is_end() {
1159
6.22k
            return None;
1160
113k
        }
1161
113k
        let rv = self.de.deserialize();
1162
113k
        self.failed = rv.is_err();
1163
113k
        Some(rv)
1164
119k
    }
Unexecuted instantiation: <deser_yaml::de::Iter<_> as core::iter::traits::iterator::Iterator>::next
1165
}
1166
1167
impl<'a> de::Deserializer<'a> for Deserializer<'a> {
1168
138k
    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'a>) -> Result<(), Error> {
1169
138k
        Deserializer::drive(self, driver)
1170
138k
    }
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`].
1178
25.1k
pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
1179
25.1k
    DeserializerConfig::new().from_str(s)
1180
25.1k
}
deser_yaml::de::from_str::<deser_value::value::Value>
Line
Count
Source
1178
25.1k
pub fn from_str<'de, T: Deserialize<'de>>(s: &'de str) -> Result<T, Error> {
1179
25.1k
    DeserializerConfig::new().from_str(s)
1180
25.1k
}
Unexecuted instantiation: deser_yaml::de::from_str::<_>
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`].
1186
0
pub fn from_slice<'de, T: Deserialize<'de>>(bytes: &'de [u8]) -> Result<T, Error> {
1187
0
    DeserializerConfig::new().from_slice(bytes)
1188
0
}
1189
1190
/// Deserializes the single document of a stream into the sink of a value
1191
/// and checks that no other document follows.
1192
25.1k
fn drive_single<'de>(
1193
25.1k
    mut deserializer: Deserializer<'de>,
1194
25.1k
    driver: &mut DeserializeDriver<'_, 'de>,
1195
25.1k
) -> Result<(), Error> {
1196
25.1k
    if deserializer.is_end() {
1197
150
        return de::Deserializer::drive(&mut EmptyDocument, driver);
1198
24.9k
    }
1199
24.9k
    de::Deserializer::drive(&mut deserializer, driver)?;
1200
15.3k
    deserializer.end()
1201
25.1k
}
1202
1203
/// The deserializer of an empty document, which is an empty plain scalar.
1204
struct EmptyDocument;
1205
1206
impl<'de> de::Deserializer<'de> for EmptyDocument {
1207
150
    fn drive(&mut self, driver: &mut DeserializeDriver<'_, 'de>) -> Result<(), Error> {
1208
150
        driver.emit(Atom::Implicit(Implicit::new("", ImplicitValue::Null)))
1209
150
    }
1210
}