serde_yaml/
loader.rs
1use crate::de::{Event, Progress};
2use crate::error::{self, Error, ErrorImpl, Result};
3use crate::libyaml::error::Mark;
4use crate::libyaml::parser::{Event as YamlEvent, Parser};
5use std::borrow::Cow;
6use std::collections::BTreeMap;
7use std::sync::Arc;
8
9pub(crate) struct Loader<'input> {
10 parser: Option<Parser<'input>>,
11 document_count: usize,
12}
13
14pub(crate) struct Document<'input> {
15 pub events: Vec<(Event<'input>, Mark)>,
16 pub error: Option<Arc<ErrorImpl>>,
17 pub aliases: BTreeMap<usize, usize>,
19}
20
21impl<'input> Loader<'input> {
22 pub fn new(progress: Progress<'input>) -> Result<Self> {
23 let input = match progress {
24 Progress::Str(s) => Cow::Borrowed(s.as_bytes()),
25 Progress::Slice(bytes) => Cow::Borrowed(bytes),
26 Progress::Read(mut rdr) => {
27 let mut buffer = Vec::new();
28 if let Err(io_error) = rdr.read_to_end(&mut buffer) {
29 return Err(error::new(ErrorImpl::Io(io_error)));
30 }
31 Cow::Owned(buffer)
32 }
33 Progress::Iterable(_) | Progress::Document(_) => unreachable!(),
34 Progress::Fail(err) => return Err(error::shared(err)),
35 };
36
37 Ok(Loader {
38 parser: Some(Parser::new(input)),
39 document_count: 0,
40 })
41 }
42
43 pub fn next_document(&mut self) -> Option<Document<'input>> {
44 let parser = match &mut self.parser {
45 Some(parser) => parser,
46 None => return None,
47 };
48
49 let first = self.document_count == 0;
50 self.document_count += 1;
51
52 let mut anchors = BTreeMap::new();
53 let mut document = Document {
54 events: Vec::new(),
55 error: None,
56 aliases: BTreeMap::new(),
57 };
58
59 loop {
60 let (event, mark) = match parser.next() {
61 Ok((event, mark)) => (event, mark),
62 Err(err) => {
63 document.error = Some(Error::from(err).shared());
64 return Some(document);
65 }
66 };
67 let event = match event {
68 YamlEvent::StreamStart => continue,
69 YamlEvent::StreamEnd => {
70 self.parser = None;
71 return if first {
72 if document.events.is_empty() {
73 document.events.push((Event::Void, mark));
74 }
75 Some(document)
76 } else {
77 None
78 };
79 }
80 YamlEvent::DocumentStart => continue,
81 YamlEvent::DocumentEnd => return Some(document),
82 YamlEvent::Alias(alias) => match anchors.get(&alias) {
83 Some(id) => Event::Alias(*id),
84 None => {
85 document.error = Some(error::new(ErrorImpl::UnknownAnchor(mark)).shared());
86 return Some(document);
87 }
88 },
89 YamlEvent::Scalar(mut scalar) => {
90 if let Some(anchor) = scalar.anchor.take() {
91 let id = anchors.len();
92 anchors.insert(anchor, id);
93 document.aliases.insert(id, document.events.len());
94 }
95 Event::Scalar(scalar)
96 }
97 YamlEvent::SequenceStart(mut sequence_start) => {
98 if let Some(anchor) = sequence_start.anchor.take() {
99 let id = anchors.len();
100 anchors.insert(anchor, id);
101 document.aliases.insert(id, document.events.len());
102 }
103 Event::SequenceStart(sequence_start)
104 }
105 YamlEvent::SequenceEnd => Event::SequenceEnd,
106 YamlEvent::MappingStart(mut mapping_start) => {
107 if let Some(anchor) = mapping_start.anchor.take() {
108 let id = anchors.len();
109 anchors.insert(anchor, id);
110 document.aliases.insert(id, document.events.len());
111 }
112 Event::MappingStart(mapping_start)
113 }
114 YamlEvent::MappingEnd => Event::MappingEnd,
115 };
116 document.events.push((event, mark));
117 }
118 }
119}