1use crate::{
8 BufferedInput, Marker,
9 input::{Input, str::StrInput},
10 scanner::{ScalarStyle, ScanError, Scanner, Span, Token, TokenType},
11};
12
13use alloc::{
14 borrow::Cow,
15 collections::BTreeMap,
16 string::{String, ToString},
17 vec::Vec,
18};
19use core::fmt::Display;
20
21#[derive(Clone, Copy, PartialEq, Debug, Eq)]
22enum State {
23 StreamStart,
24 ImplicitDocumentStart,
25 DocumentStart,
26 DocumentContent,
27 DocumentEnd,
28 BlockNode,
29 BlockSequenceFirstEntry,
30 BlockSequenceEntry,
31 IndentlessSequenceEntry,
32 BlockMappingFirstKey,
33 BlockMappingKey,
34 BlockMappingValue,
35 FlowSequenceFirstEntry,
36 FlowSequenceEntry,
37 FlowSequenceEntryMappingKey,
38 FlowSequenceEntryMappingValue,
39 FlowSequenceEntryMappingEnd(Marker),
40 FlowMappingFirstKey,
41 FlowMappingKey,
42 FlowMappingValue,
43 FlowMappingEmptyValue,
44 End,
45}
46
47#[derive(Clone, PartialEq, Debug, Eq)]
52pub enum Event<'input> {
53 Nothing,
55 StreamStart,
57 StreamEnd,
59 DocumentStart(bool),
67 DocumentEnd,
69 Alias(
71 usize,
73 ),
74 Scalar(
76 Cow<'input, str>,
77 ScalarStyle,
78 usize,
79 Option<Cow<'input, Tag>>,
80 ),
81 SequenceStart(
83 usize,
85 Option<Cow<'input, Tag>>,
87 ),
88 SequenceEnd,
90 MappingStart(
92 usize,
94 Option<Cow<'input, Tag>>,
96 ),
97 MappingEnd,
99}
100
101#[derive(Clone, PartialEq, Debug, Eq, Ord, PartialOrd, Hash)]
103pub struct Tag {
104 pub handle: String,
106 pub suffix: String,
108}
109
110impl Tag {
111 #[must_use]
120 pub fn is_yaml_core_schema(&self) -> bool {
121 self.handle == "tag:yaml.org,2002:"
122 }
123}
124
125impl Display for Tag {
126 fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
127 if self.handle == "!" {
128 write!(f, "!{}", self.suffix)
129 } else {
130 write!(f, "{}!{}", self.handle, self.suffix)
131 }
132 }
133}
134
135impl<'input> Event<'input> {
136 fn empty_scalar() -> Self {
138 Event::Scalar(Cow::default(), ScalarStyle::Plain, 0, None)
139 }
140
141 fn empty_scalar_with_anchor(anchor: usize, tag: Option<Cow<'input, Tag>>) -> Self {
143 Event::Scalar(Cow::default(), ScalarStyle::Plain, anchor, tag)
144 }
145}
146
147#[derive(Debug)]
149pub struct Parser<'input, T: Input> {
150 scanner: Scanner<'input, T>,
152 states: Vec<State>,
157 state: State,
159 token: Option<Token<'input>>,
161 current: Option<(Event<'input>, Span)>,
163 anchors: BTreeMap<Cow<'input, str>, usize>,
165 anchor_id_count: usize,
170 tags: BTreeMap<String, String>,
174 stream_end_emitted: bool,
179 keep_tags: bool,
181}
182
183impl<T: Input + Clone> Clone for Parser<'_, T> {
184 fn clone(&self) -> Self {
185 Self {
186 scanner: self.scanner.clone(),
187 states: self.states.clone(),
188 state: self.state,
189 token: self.token.clone(),
190 current: self.current.clone(),
191 anchors: self.anchors.clone(),
192 anchor_id_count: self.anchor_id_count,
193 tags: self.tags.clone(),
194 stream_end_emitted: self.stream_end_emitted,
195 keep_tags: self.keep_tags,
196 }
197 }
198}
199
200pub trait EventReceiver<'input> {
270 fn on_event(&mut self, ev: Event<'input>);
272}
273
274pub trait SpannedEventReceiver<'input> {
278 fn on_event(&mut self, ev: Event<'input>, span: Span);
280}
281
282impl<'input, R: EventReceiver<'input>> SpannedEventReceiver<'input> for R {
283 fn on_event(&mut self, ev: Event<'input>, _span: Span) {
284 self.on_event(ev);
285 }
286}
287
288pub type ParseResult<'input> = Result<(Event<'input>, Span), ScanError>;
290
291impl<'input> Parser<'input, StrInput<'input>> {
292 #[must_use]
294 pub fn new_from_str(value: &'input str) -> Self {
295 debug_print!("\x1B[;31m>>>>>>>>>> New parser from str\x1B[;0m");
296 Parser::new(StrInput::new(value))
297 }
298}
299
300impl<'input, T> Parser<'input, BufferedInput<T>>
301where
302 T: Iterator<Item = char> + 'input,
303{
304 #[must_use]
306 pub fn new_from_iter(iter: T) -> Self {
307 debug_print!("\x1B[;31m>>>>>>>>>> New parser from iter\x1B[;0m");
308 Parser::new(BufferedInput::new(iter))
309 }
310}
311
312impl<'input, T: Input> Parser<'input, T> {
313 pub fn new(src: T) -> Self {
315 Parser {
316 scanner: Scanner::new(src),
317 states: Vec::new(),
318 state: State::StreamStart,
319 token: None,
320 current: None,
321
322 anchors: BTreeMap::new(),
323 anchor_id_count: 1,
325 tags: BTreeMap::new(),
326 stream_end_emitted: false,
327 keep_tags: false,
328 }
329 }
330
331 #[must_use]
354 pub fn keep_tags(mut self, value: bool) -> Self {
355 self.keep_tags = value;
356 self
357 }
358
359 pub fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
367 if let Some(ref x) = self.current {
368 Some(Ok(x))
369 } else {
370 if self.stream_end_emitted {
371 return None;
372 }
373 match self.next_event_impl() {
374 Ok(token) => self.current = Some(token),
375 Err(e) => return Some(Err(e)),
376 }
377 self.current.as_ref().map(Ok)
378 }
379 }
380
381 pub fn next_event(&mut self) -> Option<ParseResult<'input>> {
386 if self.stream_end_emitted {
387 return None;
388 }
389
390 let tok = self.next_event_impl();
391 if matches!(tok, Ok((Event::StreamEnd, _))) {
392 self.stream_end_emitted = true;
393 }
394 Some(tok)
395 }
396
397 fn next_event_impl<'a>(&mut self) -> ParseResult<'a>
403 where
404 'input: 'a,
405 {
406 match self.current.take() {
407 None => self.parse(),
408 Some(v) => Ok(v),
409 }
410 }
411
412 fn peek_token(&mut self) -> Result<&Token<'_>, ScanError> {
414 match self.token {
415 None => {
416 self.token = Some(self.scan_next_token()?);
417 Ok(self.token.as_ref().unwrap())
418 }
419 Some(ref tok) => Ok(tok),
420 }
421 }
422
423 fn scan_next_token(&mut self) -> Result<Token<'input>, ScanError> {
427 let token = self.scanner.next();
428 match token {
429 None => match self.scanner.get_error() {
430 None => Err(ScanError::new_str(self.scanner.mark(), "unexpected eof")),
431 Some(e) => Err(e),
432 },
433 Some(tok) => Ok(tok),
434 }
435 }
436
437 fn fetch_token<'a>(&mut self) -> Token<'a>
438 where
439 'input: 'a,
440 {
441 self.token
442 .take()
443 .expect("fetch_token needs to be preceded by peek_token")
444 }
445
446 fn skip(&mut self) {
448 self.token = None;
449 }
450 fn pop_state(&mut self) {
452 self.state = self.states.pop().unwrap();
453 }
454 fn push_state(&mut self, state: State) {
456 self.states.push(state);
457 }
458
459 fn parse<'a>(&mut self) -> ParseResult<'a>
460 where
461 'input: 'a,
462 {
463 if self.state == State::End {
464 return Ok((Event::StreamEnd, Span::empty(self.scanner.mark())));
465 }
466 let (ev, mark) = self.state_machine()?;
467 Ok((ev, mark))
468 }
469
470 pub fn load<R: SpannedEventReceiver<'input>>(
483 &mut self,
484 recv: &mut R,
485 multi: bool,
486 ) -> Result<(), ScanError> {
487 if !self.scanner.stream_started() {
488 let (ev, span) = self.next_event_impl()?;
489 if ev != Event::StreamStart {
490 return Err(ScanError::new_str(
491 span.start,
492 "did not find expected <stream-start>",
493 ));
494 }
495 recv.on_event(ev, span);
496 }
497
498 if self.scanner.stream_ended() {
499 recv.on_event(Event::StreamEnd, Span::empty(self.scanner.mark()));
501 return Ok(());
502 }
503 loop {
504 let (ev, span) = self.next_event_impl()?;
505 if ev == Event::StreamEnd {
506 recv.on_event(ev, span);
507 return Ok(());
508 }
509 self.anchors.clear();
511 self.load_document(ev, span, recv)?;
512 if !multi {
513 break;
514 }
515 }
516 Ok(())
517 }
518
519 fn load_document<R: SpannedEventReceiver<'input>>(
520 &mut self,
521 first_ev: Event<'input>,
522 span: Span,
523 recv: &mut R,
524 ) -> Result<(), ScanError> {
525 if !matches!(first_ev, Event::DocumentStart(_)) {
526 return Err(ScanError::new_str(
527 span.start,
528 "did not find expected <document-start>",
529 ));
530 }
531 recv.on_event(first_ev, span);
532
533 let (ev, span) = self.next_event_impl()?;
534 self.load_node(ev, span, recv)?;
535
536 let (ev, mark) = self.next_event_impl()?;
538 assert_eq!(ev, Event::DocumentEnd);
539 recv.on_event(ev, mark);
540
541 Ok(())
542 }
543
544 fn load_node<R: SpannedEventReceiver<'input>>(
545 &mut self,
546 first_ev: Event<'input>,
547 span: Span,
548 recv: &mut R,
549 ) -> Result<(), ScanError> {
550 match first_ev {
551 Event::Alias(..) | Event::Scalar(..) => {
552 recv.on_event(first_ev, span);
553 Ok(())
554 }
555 Event::SequenceStart(..) => {
556 recv.on_event(first_ev, span);
557 self.load_sequence(recv)
558 }
559 Event::MappingStart(..) => {
560 recv.on_event(first_ev, span);
561 self.load_mapping(recv)
562 }
563 _ => {
564 #[cfg(feature = "debug_prints")]
565 std::println!("UNREACHABLE EVENT: {first_ev:?}");
566 unreachable!();
567 }
568 }
569 }
570
571 fn load_mapping<R: SpannedEventReceiver<'input>>(
572 &mut self,
573 recv: &mut R,
574 ) -> Result<(), ScanError> {
575 let (mut key_ev, mut key_mark) = self.next_event_impl()?;
576 while key_ev != Event::MappingEnd {
577 self.load_node(key_ev, key_mark, recv)?;
579
580 let (ev, mark) = self.next_event_impl()?;
582 self.load_node(ev, mark, recv)?;
583
584 let (ev, mark) = self.next_event_impl()?;
586 key_ev = ev;
587 key_mark = mark;
588 }
589 recv.on_event(key_ev, key_mark);
590 Ok(())
591 }
592
593 fn load_sequence<R: SpannedEventReceiver<'input>>(
594 &mut self,
595 recv: &mut R,
596 ) -> Result<(), ScanError> {
597 let (mut ev, mut mark) = self.next_event_impl()?;
598 while ev != Event::SequenceEnd {
599 self.load_node(ev, mark, recv)?;
600
601 let (next_ev, next_mark) = self.next_event_impl()?;
603 ev = next_ev;
604 mark = next_mark;
605 }
606 recv.on_event(ev, mark);
607 Ok(())
608 }
609
610 fn state_machine<'a>(&mut self) -> ParseResult<'a>
611 where
612 'input: 'a,
613 {
614 debug_print!("\n\x1B[;33mParser state: {:?} \x1B[;0m", self.state);
617
618 match self.state {
619 State::StreamStart => self.stream_start(),
620
621 State::ImplicitDocumentStart => self.document_start(true),
622 State::DocumentStart => self.document_start(false),
623 State::DocumentContent => self.document_content(),
624 State::DocumentEnd => self.document_end(),
625
626 State::BlockNode => self.parse_node(true, false),
627 State::BlockMappingFirstKey => self.block_mapping_key(true),
630 State::BlockMappingKey => self.block_mapping_key(false),
631 State::BlockMappingValue => self.block_mapping_value(),
632
633 State::BlockSequenceFirstEntry => self.block_sequence_entry(true),
634 State::BlockSequenceEntry => self.block_sequence_entry(false),
635
636 State::FlowSequenceFirstEntry => self.flow_sequence_entry(true),
637 State::FlowSequenceEntry => self.flow_sequence_entry(false),
638
639 State::FlowMappingFirstKey => self.flow_mapping_key(true),
640 State::FlowMappingKey => self.flow_mapping_key(false),
641 State::FlowMappingValue => self.flow_mapping_value(false),
642
643 State::IndentlessSequenceEntry => self.indentless_sequence_entry(),
644
645 State::FlowSequenceEntryMappingKey => self.flow_sequence_entry_mapping_key(),
646 State::FlowSequenceEntryMappingValue => self.flow_sequence_entry_mapping_value(),
647 State::FlowSequenceEntryMappingEnd(mark) => self.flow_sequence_entry_mapping_end(mark),
648 State::FlowMappingEmptyValue => self.flow_mapping_value(true),
649
650 State::End => unreachable!(),
652 }
653 }
654
655 fn stream_start<'a>(&mut self) -> ParseResult<'a>
656 where
657 'input: 'a,
658 {
659 match *self.peek_token()? {
660 Token(span, TokenType::StreamStart(_)) => {
661 self.state = State::ImplicitDocumentStart;
662 self.skip();
663 Ok((Event::StreamStart, span))
664 }
665 Token(span, _) => Err(ScanError::new_str(
666 span.start,
667 "did not find expected <stream-start>",
668 )),
669 }
670 }
671
672 fn document_start<'a>(&mut self, implicit: bool) -> ParseResult<'a>
673 where
674 'input: 'a,
675 {
676 while let TokenType::DocumentEnd = self.peek_token()?.1 {
677 self.skip();
678 }
679
680 match *self.peek_token()? {
681 Token(span, TokenType::StreamEnd) => {
682 self.state = State::End;
683 self.skip();
684 Ok((Event::StreamEnd, span))
685 }
686 Token(
687 _,
688 TokenType::VersionDirective(..)
689 | TokenType::TagDirective(..)
690 | TokenType::ReservedDirective(..)
691 | TokenType::DocumentStart,
692 ) => {
693 self.explicit_document_start()
695 }
696 Token(span, _) if implicit => {
697 self.parser_process_directives()?;
698 self.push_state(State::DocumentEnd);
699 self.state = State::BlockNode;
700 Ok((Event::DocumentStart(false), span))
701 }
702 _ => {
703 self.explicit_document_start()
705 }
706 }
707 }
708
709 fn parser_process_directives(&mut self) -> Result<(), ScanError> {
710 let mut version_directive_received = false;
711 loop {
712 let mut tags = BTreeMap::new();
713 match self.peek_token()? {
714 Token(span, TokenType::VersionDirective(_, _)) => {
715 if version_directive_received {
721 return Err(ScanError::new_str(
722 span.start,
723 "duplicate version directive",
724 ));
725 }
726 version_directive_received = true;
727 }
728 Token(mark, TokenType::TagDirective(handle, prefix)) => {
729 if tags.contains_key(&**handle) {
730 return Err(ScanError::new_str(
731 mark.start,
732 "the TAG directive must only be given at most once per handle in the same document",
733 ));
734 }
735 tags.insert(handle.to_string(), prefix.to_string());
736 }
737 Token(_, TokenType::ReservedDirective(_, _)) => {
738 }
740 _ => break,
741 }
742 self.tags = tags;
743 self.skip();
744 }
745 Ok(())
746 }
747
748 fn explicit_document_start<'a>(&mut self) -> ParseResult<'a>
749 where
750 'input: 'a,
751 {
752 self.parser_process_directives()?;
753 match *self.peek_token()? {
754 Token(mark, TokenType::DocumentStart) => {
755 self.push_state(State::DocumentEnd);
756 self.state = State::DocumentContent;
757 self.skip();
758 Ok((Event::DocumentStart(true), mark))
759 }
760 Token(span, _) => Err(ScanError::new_str(
761 span.start,
762 "did not find expected <document start>",
763 )),
764 }
765 }
766
767 fn document_content<'a>(&mut self) -> ParseResult<'a>
768 where
769 'input: 'a,
770 {
771 match *self.peek_token()? {
772 Token(
773 mark,
774 TokenType::VersionDirective(..)
775 | TokenType::TagDirective(..)
776 | TokenType::ReservedDirective(..)
777 | TokenType::DocumentStart
778 | TokenType::DocumentEnd
779 | TokenType::StreamEnd,
780 ) => {
781 self.pop_state();
782 Ok((Event::empty_scalar(), mark))
784 }
785 _ => self.parse_node(true, false),
786 }
787 }
788
789 fn document_end<'a>(&mut self) -> ParseResult<'a>
790 where
791 'input: 'a,
792 {
793 let mut explicit_end = false;
794 let span: Span = match *self.peek_token()? {
795 Token(span, TokenType::DocumentEnd) => {
796 explicit_end = true;
797 self.skip();
798 span
799 }
800 Token(span, _) => span,
801 };
802
803 if !self.keep_tags {
804 self.tags.clear();
805 }
806 if explicit_end {
807 self.state = State::ImplicitDocumentStart;
808 } else {
809 if let Token(
810 span,
811 TokenType::VersionDirective(..)
812 | TokenType::TagDirective(..)
813 | TokenType::ReservedDirective(..),
814 ) = *self.peek_token()?
815 {
816 return Err(ScanError::new_str(
817 span.start,
818 "missing explicit document end marker before directive",
819 ));
820 }
821 self.state = State::DocumentStart;
822 }
823
824 Ok((Event::DocumentEnd, span))
825 }
826
827 fn register_anchor(&mut self, name: Cow<'input, str>, _: &Span) -> usize {
828 let new_id = self.anchor_id_count;
834 self.anchor_id_count += 1;
835 self.anchors.insert(name, new_id);
836 new_id
837 }
838
839 fn parse_node<'a>(&mut self, block: bool, indentless_sequence: bool) -> ParseResult<'a>
840 where
841 'input: 'a,
842 {
843 let mut anchor_id = 0;
844 let mut tag = None;
845 match *self.peek_token()? {
846 Token(_, TokenType::Alias(_)) => {
847 self.pop_state();
848 if let Token(span, TokenType::Alias(name)) = self.fetch_token() {
849 match self.anchors.get(&*name) {
850 None => {
851 return Err(ScanError::new_str(
852 span.start,
853 "while parsing node, found unknown anchor",
854 ));
855 }
856 Some(id) => return Ok((Event::Alias(*id), span)),
857 }
858 }
859 unreachable!()
860 }
861 Token(_, TokenType::Anchor(_)) => {
862 if let Token(span, TokenType::Anchor(name)) = self.fetch_token() {
863 anchor_id = self.register_anchor(name, &span);
864 if let TokenType::Tag(..) = self.peek_token()?.1 {
865 if let TokenType::Tag(handle, suffix) = self.fetch_token().1 {
866 tag = Some(self.resolve_tag(span, &handle, suffix)?);
867 } else {
868 unreachable!()
869 }
870 }
871 } else {
872 unreachable!()
873 }
874 }
875 Token(mark, TokenType::Tag(..)) => {
876 if let TokenType::Tag(handle, suffix) = self.fetch_token().1 {
877 tag = Some(self.resolve_tag(mark, &handle, suffix)?);
878 if let TokenType::Anchor(_) = &self.peek_token()?.1 {
879 if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
880 anchor_id = self.register_anchor(name, &mark);
881 } else {
882 unreachable!()
883 }
884 }
885 } else {
886 unreachable!()
887 }
888 }
889 _ => {}
890 }
891 match *self.peek_token()? {
892 Token(mark, TokenType::BlockEntry) if indentless_sequence => {
893 self.state = State::IndentlessSequenceEntry;
894 Ok((Event::SequenceStart(anchor_id, tag), mark))
895 }
896 Token(_, TokenType::Scalar(..)) => {
897 self.pop_state();
898 if let Token(mark, TokenType::Scalar(style, v)) = self.fetch_token() {
899 Ok((Event::Scalar(v, style, anchor_id, tag), mark))
900 } else {
901 unreachable!()
902 }
903 }
904 Token(mark, TokenType::FlowSequenceStart) => {
905 self.state = State::FlowSequenceFirstEntry;
906 Ok((Event::SequenceStart(anchor_id, tag), mark))
907 }
908 Token(mark, TokenType::FlowMappingStart) => {
909 self.state = State::FlowMappingFirstKey;
910 Ok((Event::MappingStart(anchor_id, tag), mark))
911 }
912 Token(mark, TokenType::BlockSequenceStart) if block => {
913 self.state = State::BlockSequenceFirstEntry;
914 Ok((Event::SequenceStart(anchor_id, tag), mark))
915 }
916 Token(mark, TokenType::BlockMappingStart) if block => {
917 self.state = State::BlockMappingFirstKey;
918 Ok((Event::MappingStart(anchor_id, tag), mark))
919 }
920 Token(mark, _) if tag.is_some() || anchor_id > 0 => {
922 self.pop_state();
923 Ok((Event::empty_scalar_with_anchor(anchor_id, tag), mark))
924 }
925 Token(span, _) => Err(ScanError::new_str(
926 span.start,
927 "while parsing a node, did not find expected node content",
928 )),
929 }
930 }
931
932 fn block_mapping_key<'a>(&mut self, first: bool) -> ParseResult<'a>
933 where
934 'input: 'a,
935 {
936 if first {
938 let _ = self.peek_token()?;
939 self.skip();
941 }
942 match *self.peek_token()? {
943 Token(_, TokenType::Key) => {
944 self.skip();
945 if let Token(mark, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
946 *self.peek_token()?
947 {
948 self.state = State::BlockMappingValue;
949 Ok((Event::empty_scalar(), mark))
951 } else {
952 self.push_state(State::BlockMappingValue);
953 self.parse_node(true, true)
954 }
955 }
956 Token(mark, TokenType::Value) => {
958 self.state = State::BlockMappingValue;
959 Ok((Event::empty_scalar(), mark))
960 }
961 Token(mark, TokenType::BlockEnd) => {
962 self.pop_state();
963 self.skip();
964 Ok((Event::MappingEnd, mark))
965 }
966 Token(span, _) => Err(ScanError::new_str(
967 span.start,
968 "while parsing a block mapping, did not find expected key",
969 )),
970 }
971 }
972
973 fn block_mapping_value<'a>(&mut self) -> ParseResult<'a>
974 where
975 'input: 'a,
976 {
977 match *self.peek_token()? {
978 Token(mark, TokenType::Value) => {
979 self.skip();
980 if let Token(_, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
981 *self.peek_token()?
982 {
983 self.state = State::BlockMappingKey;
984 Ok((Event::empty_scalar(), mark))
986 } else {
987 self.push_state(State::BlockMappingKey);
988 self.parse_node(true, true)
989 }
990 }
991 Token(mark, _) => {
992 self.state = State::BlockMappingKey;
993 Ok((Event::empty_scalar(), mark))
995 }
996 }
997 }
998
999 fn flow_mapping_key<'a>(&mut self, first: bool) -> ParseResult<'a>
1000 where
1001 'input: 'a,
1002 {
1003 if first {
1004 let _ = self.peek_token()?;
1005 self.skip();
1006 }
1007 let span: Span = {
1008 match *self.peek_token()? {
1009 Token(mark, TokenType::FlowMappingEnd) => mark,
1010 Token(mark, _) => {
1011 if !first {
1012 match *self.peek_token()? {
1013 Token(_, TokenType::FlowEntry) => self.skip(),
1014 Token(span, _) => {
1015 return Err(ScanError::new_str(
1016 span.start,
1017 "while parsing a flow mapping, did not find expected ',' or '}'",
1018 ));
1019 }
1020 }
1021 }
1022
1023 match *self.peek_token()? {
1024 Token(_, TokenType::Key) => {
1025 self.skip();
1026 if let Token(
1027 mark,
1028 TokenType::Value | TokenType::FlowEntry | TokenType::FlowMappingEnd,
1029 ) = *self.peek_token()?
1030 {
1031 self.state = State::FlowMappingValue;
1032 return Ok((Event::empty_scalar(), mark));
1033 }
1034 self.push_state(State::FlowMappingValue);
1035 return self.parse_node(false, false);
1036 }
1037 Token(marker, TokenType::Value) => {
1038 self.state = State::FlowMappingValue;
1039 return Ok((Event::empty_scalar(), marker));
1040 }
1041 Token(_, TokenType::FlowMappingEnd) => (),
1042 _ => {
1043 self.push_state(State::FlowMappingEmptyValue);
1044 return self.parse_node(false, false);
1045 }
1046 }
1047
1048 mark
1049 }
1050 }
1051 };
1052
1053 self.pop_state();
1054 self.skip();
1055 Ok((Event::MappingEnd, span))
1056 }
1057
1058 fn flow_mapping_value<'a>(&mut self, empty: bool) -> ParseResult<'a>
1059 where
1060 'input: 'a,
1061 {
1062 let span: Span = {
1063 if empty {
1064 let Token(mark, _) = *self.peek_token()?;
1065 self.state = State::FlowMappingKey;
1066 return Ok((Event::empty_scalar(), mark));
1067 }
1068 match *self.peek_token()? {
1069 Token(span, TokenType::Value) => {
1070 self.skip();
1071 match self.peek_token()?.1 {
1072 TokenType::FlowEntry | TokenType::FlowMappingEnd => {}
1073 _ => {
1074 self.push_state(State::FlowMappingKey);
1075 return self.parse_node(false, false);
1076 }
1077 }
1078 span
1079 }
1080 Token(marker, _) => marker,
1081 }
1082 };
1083
1084 self.state = State::FlowMappingKey;
1085 Ok((Event::empty_scalar(), span))
1086 }
1087
1088 fn flow_sequence_entry<'a>(&mut self, first: bool) -> ParseResult<'a>
1089 where
1090 'input: 'a,
1091 {
1092 if first {
1094 let _ = self.peek_token()?;
1095 self.skip();
1097 }
1098 match *self.peek_token()? {
1099 Token(mark, TokenType::FlowSequenceEnd) => {
1100 self.pop_state();
1101 self.skip();
1102 return Ok((Event::SequenceEnd, mark));
1103 }
1104 Token(_, TokenType::FlowEntry) if !first => {
1105 self.skip();
1106 }
1107 Token(span, _) if !first => {
1108 return Err(ScanError::new_str(
1109 span.start,
1110 "while parsing a flow sequence, expected ',' or ']'",
1111 ));
1112 }
1113 _ => { }
1114 }
1115 match *self.peek_token()? {
1116 Token(mark, TokenType::FlowSequenceEnd) => {
1117 self.pop_state();
1118 self.skip();
1119 Ok((Event::SequenceEnd, mark))
1120 }
1121 Token(mark, TokenType::Key) => {
1122 self.state = State::FlowSequenceEntryMappingKey;
1123 self.skip();
1124 Ok((Event::MappingStart(0, None), mark))
1125 }
1126 _ => {
1127 self.push_state(State::FlowSequenceEntry);
1128 self.parse_node(false, false)
1129 }
1130 }
1131 }
1132
1133 fn indentless_sequence_entry<'a>(&mut self) -> ParseResult<'a>
1134 where
1135 'input: 'a,
1136 {
1137 match *self.peek_token()? {
1138 Token(mark, TokenType::BlockEntry) => {
1139 self.skip();
1140 if let Token(
1141 _,
1142 TokenType::BlockEntry | TokenType::Key | TokenType::Value | TokenType::BlockEnd,
1143 ) = *self.peek_token()?
1144 {
1145 self.state = State::IndentlessSequenceEntry;
1146 Ok((Event::empty_scalar(), mark))
1147 } else {
1148 self.push_state(State::IndentlessSequenceEntry);
1149 self.parse_node(true, false)
1150 }
1151 }
1152 Token(mark, _) => {
1153 self.pop_state();
1154 Ok((Event::SequenceEnd, mark))
1155 }
1156 }
1157 }
1158
1159 fn block_sequence_entry<'a>(&mut self, first: bool) -> ParseResult<'a>
1160 where
1161 'input: 'a,
1162 {
1163 if first {
1165 let _ = self.peek_token()?;
1166 self.skip();
1168 }
1169 match *self.peek_token()? {
1170 Token(mark, TokenType::BlockEnd) => {
1171 self.pop_state();
1172 self.skip();
1173 Ok((Event::SequenceEnd, mark))
1174 }
1175 Token(mark, TokenType::BlockEntry) => {
1176 self.skip();
1177 if let Token(_, TokenType::BlockEntry | TokenType::BlockEnd) = *self.peek_token()? {
1178 self.state = State::BlockSequenceEntry;
1179 Ok((Event::empty_scalar(), mark))
1180 } else {
1181 self.push_state(State::BlockSequenceEntry);
1182 self.parse_node(true, false)
1183 }
1184 }
1185 Token(span, _) => Err(ScanError::new_str(
1186 span.start,
1187 "while parsing a block collection, did not find expected '-' indicator",
1188 )),
1189 }
1190 }
1191
1192 fn flow_sequence_entry_mapping_key<'a>(&mut self) -> ParseResult<'a>
1193 where
1194 'input: 'a,
1195 {
1196 if let Token(mark, TokenType::Value | TokenType::FlowEntry | TokenType::FlowSequenceEnd) =
1197 *self.peek_token()?
1198 {
1199 self.skip();
1200 self.state = State::FlowSequenceEntryMappingValue;
1201 Ok((Event::empty_scalar(), mark))
1202 } else {
1203 self.push_state(State::FlowSequenceEntryMappingValue);
1204 self.parse_node(false, false)
1205 }
1206 }
1207
1208 fn flow_sequence_entry_mapping_value<'a>(&mut self) -> ParseResult<'a>
1209 where
1210 'input: 'a,
1211 {
1212 match *self.peek_token()? {
1213 Token(_, TokenType::Value) => {
1214 self.skip();
1215 self.state = State::FlowSequenceEntryMappingValue;
1216 let Token(span, ref tok) = *self.peek_token()?;
1217 if matches!(tok, TokenType::FlowEntry | TokenType::FlowSequenceEnd) {
1218 self.state = State::FlowSequenceEntryMappingEnd(span.end);
1219 Ok((Event::empty_scalar(), span))
1220 } else {
1221 self.push_state(State::FlowSequenceEntryMappingEnd(span.end));
1222 self.parse_node(false, false)
1223 }
1224 }
1225 Token(mark, _) => {
1226 self.state = State::FlowSequenceEntryMappingEnd(mark.end);
1227 Ok((Event::empty_scalar(), mark))
1228 }
1229 }
1230 }
1231
1232 #[allow(clippy::unnecessary_wraps)]
1233 fn flow_sequence_entry_mapping_end<'a>(&mut self, mark: Marker) -> ParseResult<'a>
1234 where
1235 'input: 'a,
1236 {
1237 self.state = State::FlowSequenceEntry;
1238 Ok((Event::MappingEnd, Span::empty(mark)))
1239 }
1240
1241 fn resolve_tag(
1243 &self,
1244 span: Span,
1245 handle: &str,
1246 suffix: String,
1247 ) -> Result<Cow<'input, Tag>, ScanError> {
1248 let tag = if handle == "!!" {
1249 Tag {
1252 handle: self
1253 .tags
1254 .get("!!")
1255 .map_or_else(|| "tag:yaml.org,2002:".to_string(), ToString::to_string),
1256 suffix,
1257 }
1258 } else if handle.is_empty() && suffix == "!" {
1259 match self.tags.get("") {
1261 Some(prefix) => Tag {
1262 handle: prefix.clone(),
1263 suffix,
1264 },
1265 None => Tag {
1266 handle: String::new(),
1267 suffix,
1268 },
1269 }
1270 } else {
1271 let prefix = self.tags.get(handle);
1273 if let Some(prefix) = prefix {
1274 Tag {
1275 handle: prefix.clone(),
1276 suffix,
1277 }
1278 } else {
1279 if handle.len() >= 2 && handle.starts_with('!') && handle.ends_with('!') {
1284 return Err(ScanError::new_str(span.start, "the handle wasn't declared"));
1285 }
1286 Tag {
1287 handle: handle.to_string(),
1288 suffix,
1289 }
1290 }
1291 };
1292 Ok(Cow::Owned(tag))
1293 }
1294}
1295
1296impl<'input, T: Input> Iterator for Parser<'input, T> {
1297 type Item = Result<(Event<'input>, Span), ScanError>;
1298
1299 fn next(&mut self) -> Option<Self::Item> {
1300 self.next_event()
1301 }
1302}
1303
1304#[cfg(test)]
1305mod test {
1306 use super::{Event, Parser};
1307
1308 #[test]
1309 fn test_peek_eq_parse() {
1310 let s = "
1311a0 bb: val
1312a1: &x
1313 b1: 4
1314 b2: d
1315a2: 4
1316a3: [1, 2, 3]
1317a4:
1318 - [a1, a2]
1319 - 2
1320a5: *x
1321";
1322 let mut p = Parser::new_from_str(s);
1323 loop {
1324 let event_peek = p.peek().unwrap().unwrap().clone();
1325 let event = p.next_event().unwrap().unwrap();
1326 assert_eq!(event, event_peek);
1327 if event.0 == Event::StreamEnd {
1328 break;
1329 }
1330 }
1331 }
1332
1333 #[test]
1334 fn test_keep_tags_across_multiple_documents() {
1335 let text = r#"
1336%YAML 1.1
1337%TAG !t! tag:test,2024:
1338--- !t!1 &1
1339foo: "bar"
1340--- !t!2 &2
1341baz: "qux"
1342"#;
1343 for x in Parser::new_from_str(text).keep_tags(true) {
1344 let x = x.unwrap();
1345 if let Event::MappingStart(_, tag) = x.0 {
1346 let tag = tag.unwrap();
1347 assert_eq!(tag.handle, "tag:test,2024:");
1348 }
1349 }
1350
1351 for x in Parser::new_from_str(text).keep_tags(false) {
1352 if x.is_err() {
1353 return;
1355 }
1356 }
1357 panic!("Test failed, did not encounter error")
1358 }
1359}