1use std::io::BufRead;
2
3use crate::{
4 AliasData, Anchors, DEFAULT_MAPPING_TAG, DEFAULT_SCALAR_TAG, DEFAULT_SEQUENCE_TAG, Emitter,
5 Error, Event, EventData, MappingStyle, Mark, Parser, ParserInner, Result, ScalarStyle,
6 SequenceStyle, TagDirective, VersionDirective,
7};
8
9#[derive(Clone, Debug)]
11#[non_exhaustive]
12pub struct Document {
13 pub nodes: Vec<Node>,
15 pub version_directive: Option<VersionDirective>,
17 pub tag_directives: Vec<TagDirective>,
19 pub start_implicit: bool,
21 pub end_implicit: bool,
23 pub start_mark: Mark,
25 pub end_mark: Mark,
27}
28
29#[derive(Clone, Default, Debug)]
31#[non_exhaustive]
32pub struct Node {
33 pub data: NodeData,
35 pub tag: Option<String>,
37 pub start_mark: Mark,
39 pub end_mark: Mark,
41}
42
43#[derive(Clone, Default, Debug)]
45pub enum NodeData {
46 #[default]
48 NoNode,
49 Scalar {
51 value: String,
53 style: ScalarStyle,
55 },
56 Sequence {
58 items: Vec<NodeItem>,
60 style: SequenceStyle,
62 },
63 Mapping {
65 pairs: Vec<NodePair>,
67 style: MappingStyle,
69 },
70}
71
72pub type NodeItem = i32;
74
75#[derive(Copy, Clone, Default, Debug)]
77#[non_exhaustive]
78pub struct NodePair {
79 pub key: i32,
81 pub value: i32,
83}
84
85impl Document {
86 pub fn new(
88 version_directive: Option<VersionDirective>,
89 tag_directives_in: &[TagDirective],
90 start_implicit: bool,
91 end_implicit: bool,
92 ) -> Document {
93 let nodes = Vec::with_capacity(16);
94 let tag_directives = tag_directives_in.to_vec();
95
96 Document {
97 nodes,
98 version_directive,
99 tag_directives,
100 start_implicit,
101 end_implicit,
102 start_mark: Mark::default(),
103 end_mark: Mark::default(),
104 }
105 }
106
107 pub fn get_node_mut(&mut self, index: i32) -> Option<&mut Node> {
111 self.nodes.get_mut(index as usize - 1)
112 }
113
114 pub fn get_node(&self, index: i32) -> Option<&Node> {
118 self.nodes.get(index as usize - 1)
119 }
120
121 pub fn get_root_node(&mut self) -> Option<&mut Node> {
129 self.nodes.get_mut(0)
130 }
131
132 #[must_use]
138 pub fn add_scalar(&mut self, tag: Option<&str>, value: &str, style: ScalarStyle) -> i32 {
139 let mark = Mark {
140 index: 0_u64,
141 line: 0_u64,
142 column: 0_u64,
143 };
144 let tag = tag.unwrap_or(DEFAULT_SCALAR_TAG);
145 let tag_copy = String::from(tag);
146 let value_copy = String::from(value);
147 let node = Node {
148 data: NodeData::Scalar {
149 value: value_copy,
150 style,
151 },
152 tag: Some(tag_copy),
153 start_mark: mark,
154 end_mark: mark,
155 };
156 self.nodes.push(node);
157 self.nodes.len() as i32
158 }
159
160 #[must_use]
166 pub fn add_sequence(&mut self, tag: Option<&str>, style: SequenceStyle) -> i32 {
167 let mark = Mark {
168 index: 0_u64,
169 line: 0_u64,
170 column: 0_u64,
171 };
172
173 let items = Vec::with_capacity(16);
174 let tag = tag.unwrap_or(DEFAULT_SEQUENCE_TAG);
175 let tag_copy = String::from(tag);
176 let node = Node {
177 data: NodeData::Sequence { items, style },
178 tag: Some(tag_copy),
179 start_mark: mark,
180 end_mark: mark,
181 };
182 self.nodes.push(node);
183 self.nodes.len() as i32
184 }
185
186 #[must_use]
192 pub fn add_mapping(&mut self, tag: Option<&str>, style: MappingStyle) -> i32 {
193 let mark = Mark {
194 index: 0_u64,
195 line: 0_u64,
196 column: 0_u64,
197 };
198 let pairs = Vec::with_capacity(16);
199 let tag = tag.unwrap_or(DEFAULT_MAPPING_TAG);
200 let tag_copy = String::from(tag);
201
202 let node = Node {
203 data: NodeData::Mapping { pairs, style },
204 tag: Some(tag_copy),
205 start_mark: mark,
206 end_mark: mark,
207 };
208
209 self.nodes.push(node);
210 self.nodes.len() as i32
211 }
212
213 pub fn append_sequence_item(&mut self, sequence: i32, item: i32) {
215 assert!(sequence > 0 && sequence as usize - 1 < self.nodes.len());
216 assert!(matches!(
217 &self.nodes[sequence as usize - 1].data,
218 NodeData::Sequence { .. }
219 ));
220 assert!(item > 0 && item as usize - 1 < self.nodes.len());
221 if let NodeData::Sequence { items, .. } = &mut self.nodes[sequence as usize - 1].data {
222 items.push(item);
223 }
224 }
225
226 pub fn yaml_document_append_mapping_pair(&mut self, mapping: i32, key: i32, value: i32) {
228 assert!(mapping > 0 && mapping as usize - 1 < self.nodes.len());
229 assert!(matches!(
230 &self.nodes[mapping as usize - 1].data,
231 NodeData::Mapping { .. }
232 ));
233 assert!(key > 0 && key as usize - 1 < self.nodes.len());
234 assert!(value > 0 && value as usize - 1 < self.nodes.len());
235 let pair = NodePair { key, value };
236 if let NodeData::Mapping { pairs, .. } = &mut self.nodes[mapping as usize - 1].data {
237 pairs.push(pair);
238 }
239 }
240
241 pub fn load<R: BufRead>(parser: &mut Parser<R>) -> Result<Document> {
252 let mut document = Document::new(None, &[], false, false);
253 document.nodes.reserve(16);
254
255 if !parser.scanner.stream_start_produced {
256 match parser.parse() {
257 Ok(Event {
258 data: EventData::StreamStart { .. },
259 ..
260 }) => (),
261 Ok(_) => panic!("expected stream start"),
262 Err(err) => {
263 parser.inner.delete_aliases();
264 return Err(err);
265 }
266 }
267 }
268 if parser.scanner.stream_end_produced {
269 return Ok(document);
270 }
271 let err: Error;
272 match parser.parse() {
273 Ok(event) => {
274 if let EventData::StreamEnd = &event.data {
275 return Ok(document);
276 }
277 parser.inner.aliases.reserve(16);
278 match document.load_document(parser, event) {
279 Ok(()) => {
280 parser.inner.delete_aliases();
281 return Ok(document);
282 }
283 Err(e) => err = e,
284 }
285 }
286 Err(e) => err = e,
287 }
288 parser.inner.delete_aliases();
289 Err(err)
290 }
291
292 fn load_document<R: BufRead>(&mut self, parser: &mut Parser<R>, event: Event) -> Result<()> {
293 let mut ctx = vec![];
294 if let EventData::DocumentStart {
295 version_directive,
296 tag_directives,
297 implicit,
298 } = event.data
299 {
300 self.version_directive = version_directive;
301 self.tag_directives = tag_directives;
302 self.start_implicit = implicit;
303 self.start_mark = event.start_mark;
304 ctx.reserve(16);
305 if let Err(err) = self.load_nodes(parser, &mut ctx) {
306 ctx.clear();
307 return Err(err);
308 }
309 ctx.clear();
310 Ok(())
311 } else {
312 panic!("Expected YAML_DOCUMENT_START_EVENT")
313 }
314 }
315
316 fn load_nodes<R: BufRead>(&mut self, parser: &mut Parser<R>, ctx: &mut Vec<i32>) -> Result<()> {
317 let end_implicit;
318 let end_mark;
319
320 loop {
321 let event = parser.parse()?;
322 match event.data {
323 EventData::StreamStart { .. } => panic!("unexpected stream start event"),
324 EventData::StreamEnd => panic!("unexpected stream end event"),
325 EventData::DocumentStart { .. } => panic!("unexpected document start event"),
326 EventData::DocumentEnd { implicit } => {
327 end_implicit = implicit;
328 end_mark = event.end_mark;
329 break;
330 }
331 EventData::Alias { .. } => {
332 self.load_alias(&parser.inner, event, ctx)?;
333 }
334 EventData::Scalar { .. } => {
335 self.load_scalar(&mut parser.inner, event, ctx)?;
336 }
337 EventData::SequenceStart { .. } => {
338 self.load_sequence(&mut parser.inner, event, ctx)?;
339 }
340 EventData::SequenceEnd => {
341 self.load_sequence_end(event, ctx)?;
342 }
343 EventData::MappingStart { .. } => {
344 self.load_mapping(&mut parser.inner, event, ctx)?;
345 }
346 EventData::MappingEnd => {
347 self.load_mapping_end(event, ctx)?;
348 }
349 }
350 }
351 self.end_implicit = end_implicit;
352 self.end_mark = end_mark;
353 Ok(())
354 }
355
356 fn register_anchor(
357 &mut self,
358 parser: &mut ParserInner,
359 index: i32,
360 anchor: Option<String>,
361 ) -> Result<()> {
362 let anchor = match anchor {
363 Some(anchor) => anchor,
364 None => return Ok(()),
365 };
366 let data = AliasData {
367 anchor,
368 index,
369 mark: self.nodes[index as usize - 1].start_mark,
370 };
371 for alias_data in &parser.aliases {
372 if alias_data.anchor == data.anchor {
373 return Err(Error::composer(
374 "found duplicate anchor; first occurrence",
375 alias_data.mark,
376 "second occurrence",
377 data.mark,
378 ));
379 }
380 }
381 parser.aliases.push(data);
382 Ok(())
383 }
384
385 fn load_node_add(&mut self, ctx: &[i32], index: i32) -> Result<()> {
386 let parent_index = match ctx.last() {
387 Some(parent_index) => parent_index,
388 None => return Ok(()),
389 };
390 let parent_index = *parent_index;
391 let parent = &mut self.nodes[parent_index as usize - 1];
392 match parent.data {
393 NodeData::Sequence { ref mut items, .. } => {
394 items.push(index);
395 }
396 NodeData::Mapping { ref mut pairs, .. } => match pairs.last_mut() {
397 Some(pair @ NodePair { value: 0, .. }) => {
399 pair.value = index;
400 }
401 _ => pairs.push(NodePair {
403 key: index,
404 value: 0,
405 }),
406 },
407 _ => {
408 panic!("document parent node is not a sequence or a mapping")
409 }
410 }
411 Ok(())
412 }
413
414 fn load_alias(&mut self, parser: &ParserInner, event: Event, ctx: &[i32]) -> Result<()> {
415 let anchor = match &event.data {
416 EventData::Alias { anchor } => anchor,
417 _ => unreachable!(),
418 };
419
420 for alias_data in &parser.aliases {
421 if alias_data.anchor == *anchor {
422 return self.load_node_add(ctx, alias_data.index);
423 }
424 }
425
426 Err(Error::composer(
427 "",
428 Mark::default(),
429 "found undefined alias",
430 event.start_mark,
431 ))
432 }
433
434 fn load_scalar(&mut self, parser: &mut ParserInner, event: Event, ctx: &[i32]) -> Result<()> {
435 let (mut tag, value, style, anchor) = match event.data {
436 EventData::Scalar {
437 tag,
438 value,
439 style,
440 anchor,
441 ..
442 } => (tag, value, style, anchor),
443 _ => unreachable!(),
444 };
445
446 if tag.is_none() || tag.as_deref() == Some("!") {
447 tag = Some(String::from(DEFAULT_SCALAR_TAG));
448 }
449 let node = Node {
450 data: NodeData::Scalar { value, style },
451 tag,
452 start_mark: event.start_mark,
453 end_mark: event.end_mark,
454 };
455 self.nodes.push(node);
456 let index: i32 = self.nodes.len() as i32;
457 self.register_anchor(parser, index, anchor)?;
458 self.load_node_add(ctx, index)
459 }
460
461 fn load_sequence(
462 &mut self,
463 parser: &mut ParserInner,
464 event: Event,
465 ctx: &mut Vec<i32>,
466 ) -> Result<()> {
467 let (anchor, mut tag, style) = match event.data {
468 EventData::SequenceStart {
469 anchor,
470 tag,
471 style,
472 ..
473 } => (anchor, tag, style),
474 _ => unreachable!(),
475 };
476
477 let mut items = Vec::with_capacity(16);
478
479 if tag.is_none() || tag.as_deref() == Some("!") {
480 tag = Some(String::from(DEFAULT_SEQUENCE_TAG));
481 }
482
483 let node = Node {
484 data: NodeData::Sequence {
485 items: core::mem::take(&mut items),
486 style,
487 },
488 tag,
489 start_mark: event.start_mark,
490 end_mark: event.end_mark,
491 };
492
493 self.nodes.push(node);
494 let index: i32 = self.nodes.len() as i32;
495 self.register_anchor(parser, index, anchor)?;
496 self.load_node_add(ctx, index)?;
497 ctx.push(index);
498 Ok(())
499 }
500
501 fn load_sequence_end(&mut self, event: Event, ctx: &mut Vec<i32>) -> Result<()> {
502 let index = match ctx.last().copied() {
503 Some(index) => index,
504 None => panic!("sequence_end without a current sequence"),
505 };
506 assert!(matches!(
507 self.nodes[index as usize - 1].data,
508 NodeData::Sequence { .. }
509 ));
510 self.nodes[index as usize - 1].end_mark = event.end_mark;
511 ctx.pop();
512 Ok(())
513 }
514
515 fn load_mapping(
516 &mut self,
517 parser: &mut ParserInner,
518 event: Event,
519 ctx: &mut Vec<i32>,
520 ) -> Result<()> {
521 let (anchor, mut tag, style) = match event.data {
522 EventData::MappingStart {
523 anchor,
524 tag,
525 style,
526 ..
527 } => (anchor, tag, style),
528 _ => unreachable!(),
529 };
530
531 let mut pairs = Vec::with_capacity(16);
532
533 if tag.is_none() || tag.as_deref() == Some("!") {
534 tag = Some(String::from(DEFAULT_MAPPING_TAG));
535 }
536 let node = Node {
537 data: NodeData::Mapping {
538 pairs: core::mem::take(&mut pairs),
539 style,
540 },
541 tag,
542 start_mark: event.start_mark,
543 end_mark: event.end_mark,
544 };
545 self.nodes.push(node);
546 let index: i32 = self.nodes.len() as i32;
547 self.register_anchor(parser, index, anchor)?;
548 self.load_node_add(ctx, index)?;
549 ctx.push(index);
550 Ok(())
551 }
552
553 fn load_mapping_end(&mut self, event: Event, ctx: &mut Vec<i32>) -> Result<()> {
554 let index = match ctx.last().copied() {
555 Some(index) => index,
556 None => panic!("mapping_end without a current mapping"),
557 };
558 assert!(matches!(
559 self.nodes[index as usize - 1].data,
560 NodeData::Mapping { .. }
561 ));
562 self.nodes[index as usize - 1].end_mark = event.end_mark;
563 ctx.pop();
564 Ok(())
565 }
566
567 pub fn dump(mut self, emitter: &mut Emitter) -> Result<()> {
572 if !emitter.opened {
573 if let Err(err) = emitter.open() {
574 emitter.reset_anchors();
575 return Err(err);
576 }
577 }
578 if self.nodes.is_empty() {
579 emitter.close()?;
583 } else {
584 assert!(emitter.opened);
585 emitter.anchors = vec![Anchors::default(); self.nodes.len()];
586 let event = Event::new(EventData::DocumentStart {
587 version_directive: self.version_directive,
588 tag_directives: core::mem::take(&mut self.tag_directives),
589 implicit: self.start_implicit,
590 });
591 emitter.emit(event)?;
592 self.anchor_node(emitter, 1);
593 self.dump_node(emitter, 1)?;
594 let event = Event::document_end(self.end_implicit);
595 emitter.emit(event)?;
596 }
597
598 emitter.reset_anchors();
599 Ok(())
600 }
601
602 fn anchor_node(&self, emitter: &mut Emitter, index: i32) {
603 let node = &self.nodes[index as usize - 1];
604 emitter.anchors[index as usize - 1].references += 1;
605 if emitter.anchors[index as usize - 1].references == 1 {
606 match &node.data {
607 NodeData::Sequence { items, .. } => {
608 for item in items {
609 emitter.anchor_node_sub(*item);
610 }
611 }
612 NodeData::Mapping { pairs, .. } => {
613 for pair in pairs {
614 emitter.anchor_node_sub(pair.key);
615 emitter.anchor_node_sub(pair.value);
616 }
617 }
618 _ => {}
619 }
620 } else if emitter.anchors[index as usize - 1].references == 2 {
621 emitter.last_anchor_id += 1;
622 emitter.anchors[index as usize - 1].anchor = emitter.last_anchor_id;
623 }
624 }
625
626 fn dump_node(&mut self, emitter: &mut Emitter, index: i32) -> Result<()> {
627 assert!(index > 0);
628 let node = &mut self.nodes[index as usize - 1];
629 let anchor_id: i32 = emitter.anchors[index as usize - 1].anchor;
630 let mut anchor: Option<String> = None;
631 if anchor_id != 0 {
632 anchor = Some(Emitter::generate_anchor(anchor_id));
633 }
634 if emitter.anchors[index as usize - 1].serialized {
635 return Self::dump_alias(emitter, anchor.unwrap());
636 }
637 emitter.anchors[index as usize - 1].serialized = true;
638
639 let node = core::mem::take(node);
640 match node.data {
641 NodeData::Scalar { .. } => Self::dump_scalar(emitter, node, anchor),
642 NodeData::Sequence { .. } => self.dump_sequence(emitter, node, anchor),
643 NodeData::Mapping { .. } => self.dump_mapping(emitter, node, anchor),
644 _ => unreachable!("document node is neither a scalar, sequence, or a mapping"),
645 }
646 }
647
648 fn dump_alias(emitter: &mut Emitter, anchor: String) -> Result<()> {
649 let event = Event::new(EventData::Alias { anchor });
650 emitter.emit(event)
651 }
652
653 fn dump_scalar(emitter: &mut Emitter, node: Node, anchor: Option<String>) -> Result<()> {
654 let plain_implicit = node.tag.as_deref() == Some(DEFAULT_SCALAR_TAG);
655 let quoted_implicit = node.tag.as_deref() == Some(DEFAULT_SCALAR_TAG); let (value, style) = match node.data {
658 NodeData::Scalar { value, style } => (value, style),
659 _ => unreachable!(),
660 };
661 let event = Event::new(EventData::Scalar {
662 anchor,
663 tag: node.tag,
664 value,
665 plain_implicit,
666 quoted_implicit,
667 style,
668 });
669 emitter.emit(event)
670 }
671
672 fn dump_sequence(
673 &mut self,
674 emitter: &mut Emitter,
675 node: Node,
676 anchor: Option<String>,
677 ) -> Result<()> {
678 let implicit = node.tag.as_deref() == Some(DEFAULT_SEQUENCE_TAG);
679
680 let (items, style) = match node.data {
681 NodeData::Sequence { items, style } => (items, style),
682 _ => unreachable!(),
683 };
684 let event = Event::new(EventData::SequenceStart {
685 anchor,
686 tag: node.tag,
687 implicit,
688 style,
689 });
690
691 emitter.emit(event)?;
692 for item in items {
693 self.dump_node(emitter, item)?;
694 }
695 let event = Event::sequence_end();
696 emitter.emit(event)
697 }
698
699 fn dump_mapping(
700 &mut self,
701 emitter: &mut Emitter,
702 node: Node,
703 anchor: Option<String>,
704 ) -> Result<()> {
705 let implicit = node.tag.as_deref() == Some(DEFAULT_MAPPING_TAG);
706
707 let (pairs, style) = match node.data {
708 NodeData::Mapping { pairs, style } => (pairs, style),
709 _ => unreachable!(),
710 };
711 let event = Event::new(EventData::MappingStart {
712 anchor,
713 tag: node.tag,
714 implicit,
715 style,
716 });
717
718 emitter.emit(event)?;
719 for pair in pairs {
720 self.dump_node(emitter, pair.key)?;
721 self.dump_node(emitter, pair.value)?;
722 }
723 let event = Event::mapping_end();
724 emitter.emit(event)
725 }
726}