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 | TokenType::ByteOrderMark = 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 let mut tags = BTreeMap::new();
712 loop {
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.skip();
743 }
744 self.tags.extend(tags);
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, TokenType::ByteOrderMark) => Err(ScanError::new_str(
761 span.start,
762 "a byte order mark must not appear inside a document",
763 )),
764 Token(span, _) => Err(ScanError::new_str(
765 span.start,
766 "did not find expected <document start>",
767 )),
768 }
769 }
770
771 fn document_content<'a>(&mut self) -> ParseResult<'a>
772 where
773 'input: 'a,
774 {
775 match *self.peek_token()? {
776 Token(
777 mark,
778 TokenType::VersionDirective(..)
779 | TokenType::TagDirective(..)
780 | TokenType::ReservedDirective(..)
781 | TokenType::DocumentStart
782 | TokenType::DocumentEnd
783 | TokenType::ByteOrderMark
784 | TokenType::StreamEnd,
785 ) => {
786 self.pop_state();
787 Ok((Event::empty_scalar(), mark))
789 }
790 _ => self.parse_node(true, false),
791 }
792 }
793
794 fn document_end<'a>(&mut self) -> ParseResult<'a>
795 where
796 'input: 'a,
797 {
798 if let Token(span, TokenType::ByteOrderMark) = *self.peek_token()? {
802 while let TokenType::ByteOrderMark = self.peek_token()?.1 {
803 self.skip();
804 }
805
806 match self.peek_token()?.1 {
807 TokenType::DocumentStart | TokenType::DocumentEnd | TokenType::StreamEnd => {}
808 _ => {
809 return Err(ScanError::new_str(
810 span.start,
811 "a byte order mark must not appear inside a document",
812 ));
813 }
814 }
815 }
816
817 let mut explicit_end = false;
818 let span: Span = match *self.peek_token()? {
819 Token(span, TokenType::DocumentEnd) => {
820 explicit_end = true;
821 self.skip();
822 span
823 }
824 Token(span, _) => span,
825 };
826
827 if !self.keep_tags {
828 self.tags.clear();
829 }
830 if explicit_end {
831 self.state = State::ImplicitDocumentStart;
832 } else {
833 if let Token(
834 span,
835 TokenType::VersionDirective(..)
836 | TokenType::TagDirective(..)
837 | TokenType::ReservedDirective(..),
838 ) = *self.peek_token()?
839 {
840 return Err(ScanError::new_str(
841 span.start,
842 "missing explicit document end marker before directive",
843 ));
844 }
845 self.state = State::DocumentStart;
846 }
847
848 Ok((Event::DocumentEnd, span))
849 }
850
851 fn register_anchor(&mut self, name: Cow<'input, str>, _: &Span) -> usize {
852 let new_id = self.anchor_id_count;
858 self.anchor_id_count += 1;
859 self.anchors.insert(name, new_id);
860 new_id
861 }
862
863 fn parse_node<'a>(&mut self, block: bool, indentless_sequence: bool) -> ParseResult<'a>
864 where
865 'input: 'a,
866 {
867 let mut anchor_id = 0;
868 let mut tag = None;
869 let start_mark = self.peek_token()?.0.start;
870 let mut end_mark = start_mark;
871 match *self.peek_token()? {
872 Token(_, TokenType::Alias(_)) => {
873 self.pop_state();
874 if let Token(span, TokenType::Alias(name)) = self.fetch_token() {
875 match self.anchors.get(&*name) {
876 None => {
877 return Err(ScanError::new_str(
878 span.start,
879 "while parsing node, found unknown anchor",
880 ));
881 }
882 Some(id) => return Ok((Event::Alias(*id), span)),
883 }
884 }
885 unreachable!()
886 }
887 Token(_, TokenType::Anchor(_)) => {
888 if let Token(span, TokenType::Anchor(name)) = self.fetch_token() {
889 anchor_id = self.register_anchor(name, &span);
890 end_mark = span.end;
891 if let TokenType::Tag(..) = self.peek_token()?.1 {
892 if let Token(mark, TokenType::Tag(handle, suffix)) = self.fetch_token() {
893 tag = Some(self.resolve_tag(span, &handle, suffix)?);
894 end_mark = mark.end;
895 } else {
896 unreachable!()
897 }
898 }
899 } else {
900 unreachable!()
901 }
902 }
903 Token(mark, TokenType::Tag(..)) => {
904 if let TokenType::Tag(handle, suffix) = self.fetch_token().1 {
905 tag = Some(self.resolve_tag(mark, &handle, suffix)?);
906 end_mark = mark.end;
907 if let TokenType::Anchor(_) = &self.peek_token()?.1 {
908 if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
909 anchor_id = self.register_anchor(name, &mark);
910 end_mark = mark.end;
911 } else {
912 unreachable!()
913 }
914 }
915 } else {
916 unreachable!()
917 }
918 }
919 _ => {}
920 }
921 let (event, end_mark) = match *self.peek_token()? {
922 Token(mark, TokenType::BlockEntry) if indentless_sequence => {
923 self.state = State::IndentlessSequenceEntry;
924 (Event::SequenceStart(anchor_id, tag), mark.end)
925 }
926 Token(_, TokenType::Scalar(..)) => {
927 self.pop_state();
928 if let Token(mark, TokenType::Scalar(style, v)) = self.fetch_token() {
929 (Event::Scalar(v, style, anchor_id, tag), mark.end)
930 } else {
931 unreachable!()
932 }
933 }
934 Token(mark, TokenType::FlowSequenceStart) => {
935 self.state = State::FlowSequenceFirstEntry;
936 (Event::SequenceStart(anchor_id, tag), mark.end)
937 }
938 Token(mark, TokenType::FlowMappingStart) => {
939 self.state = State::FlowMappingFirstKey;
940 (Event::MappingStart(anchor_id, tag), mark.end)
941 }
942 Token(mark, TokenType::BlockSequenceStart) if block => {
943 self.state = State::BlockSequenceFirstEntry;
944 (Event::SequenceStart(anchor_id, tag), mark.end)
945 }
946 Token(mark, TokenType::BlockMappingStart) if block => {
947 self.state = State::BlockMappingFirstKey;
948 (Event::MappingStart(anchor_id, tag), mark.end)
949 }
950 Token(..) if tag.is_some() || anchor_id > 0 => {
952 self.pop_state();
953 (Event::empty_scalar_with_anchor(anchor_id, tag), end_mark)
954 }
955 Token(span, _) => {
956 return Err(ScanError::new_str(
957 span.start,
958 "while parsing a node, did not find expected node content",
959 ));
960 }
961 };
962 Ok((event, Span::new(start_mark, end_mark)))
963 }
964
965 fn block_mapping_key<'a>(&mut self, first: bool) -> ParseResult<'a>
966 where
967 'input: 'a,
968 {
969 if first {
971 let _ = self.peek_token()?;
972 self.skip();
974 }
975 match *self.peek_token()? {
976 Token(_, TokenType::Key) => {
977 self.skip();
978 if let Token(mark, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
979 *self.peek_token()?
980 {
981 self.state = State::BlockMappingValue;
982 Ok((Event::empty_scalar(), mark))
984 } else {
985 self.push_state(State::BlockMappingValue);
986 self.parse_node(true, true)
987 }
988 }
989 Token(mark, TokenType::Value) => {
991 self.state = State::BlockMappingValue;
992 Ok((Event::empty_scalar(), mark))
993 }
994 Token(mark, TokenType::BlockEnd) => {
995 self.pop_state();
996 self.skip();
997 Ok((Event::MappingEnd, mark))
998 }
999 Token(span, _) => Err(ScanError::new_str(
1000 span.start,
1001 "while parsing a block mapping, did not find expected key",
1002 )),
1003 }
1004 }
1005
1006 fn block_mapping_value<'a>(&mut self) -> ParseResult<'a>
1007 where
1008 'input: 'a,
1009 {
1010 match *self.peek_token()? {
1011 Token(mark, TokenType::Value) => {
1012 self.skip();
1013 if let Token(_, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
1014 *self.peek_token()?
1015 {
1016 self.state = State::BlockMappingKey;
1017 Ok((Event::empty_scalar(), mark))
1019 } else {
1020 self.push_state(State::BlockMappingKey);
1021 self.parse_node(true, true)
1022 }
1023 }
1024 Token(mark, _) => {
1025 self.state = State::BlockMappingKey;
1026 Ok((Event::empty_scalar(), mark))
1028 }
1029 }
1030 }
1031
1032 fn flow_mapping_key<'a>(&mut self, first: bool) -> ParseResult<'a>
1033 where
1034 'input: 'a,
1035 {
1036 if first {
1037 let _ = self.peek_token()?;
1038 self.skip();
1039 }
1040 let span: Span = {
1041 match *self.peek_token()? {
1042 Token(mark, TokenType::FlowMappingEnd) => mark,
1043 Token(mark, _) => {
1044 if !first {
1045 match *self.peek_token()? {
1046 Token(_, TokenType::FlowEntry) => self.skip(),
1047 Token(span, _) => {
1048 return Err(ScanError::new_str(
1049 span.start,
1050 "while parsing a flow mapping, did not find expected ',' or '}'",
1051 ));
1052 }
1053 }
1054 }
1055
1056 match *self.peek_token()? {
1057 Token(_, TokenType::Key) => {
1058 self.skip();
1059 if let Token(
1060 mark,
1061 TokenType::Value | TokenType::FlowEntry | TokenType::FlowMappingEnd,
1062 ) = *self.peek_token()?
1063 {
1064 self.state = State::FlowMappingValue;
1065 return Ok((Event::empty_scalar(), mark));
1066 }
1067 self.push_state(State::FlowMappingValue);
1068 return self.parse_node(false, false);
1069 }
1070 Token(marker, TokenType::Value) => {
1071 self.state = State::FlowMappingValue;
1072 return Ok((Event::empty_scalar(), marker));
1073 }
1074 Token(_, TokenType::FlowMappingEnd) => (),
1075 _ => {
1076 self.push_state(State::FlowMappingEmptyValue);
1077 return self.parse_node(false, false);
1078 }
1079 }
1080
1081 mark
1082 }
1083 }
1084 };
1085
1086 self.pop_state();
1087 self.skip();
1088 Ok((Event::MappingEnd, span))
1089 }
1090
1091 fn flow_mapping_value<'a>(&mut self, empty: bool) -> ParseResult<'a>
1092 where
1093 'input: 'a,
1094 {
1095 let span: Span = {
1096 if empty {
1097 let Token(mark, _) = *self.peek_token()?;
1098 self.state = State::FlowMappingKey;
1099 return Ok((Event::empty_scalar(), mark));
1100 }
1101 match *self.peek_token()? {
1102 Token(span, TokenType::Value) => {
1103 self.skip();
1104 match self.peek_token()?.1 {
1105 TokenType::FlowEntry | TokenType::FlowMappingEnd => {}
1106 _ => {
1107 self.push_state(State::FlowMappingKey);
1108 return self.parse_node(false, false);
1109 }
1110 }
1111 span
1112 }
1113 Token(marker, _) => marker,
1114 }
1115 };
1116
1117 self.state = State::FlowMappingKey;
1118 Ok((Event::empty_scalar(), span))
1119 }
1120
1121 fn flow_sequence_entry<'a>(&mut self, first: bool) -> ParseResult<'a>
1122 where
1123 'input: 'a,
1124 {
1125 if first {
1127 let _ = self.peek_token()?;
1128 self.skip();
1130 }
1131 match *self.peek_token()? {
1132 Token(mark, TokenType::FlowSequenceEnd) => {
1133 self.pop_state();
1134 self.skip();
1135 return Ok((Event::SequenceEnd, mark));
1136 }
1137 Token(_, TokenType::FlowEntry) if !first => {
1138 self.skip();
1139 }
1140 Token(span, _) if !first => {
1141 return Err(ScanError::new_str(
1142 span.start,
1143 "while parsing a flow sequence, expected ',' or ']'",
1144 ));
1145 }
1146 _ => { }
1147 }
1148 match *self.peek_token()? {
1149 Token(mark, TokenType::FlowSequenceEnd) => {
1150 self.pop_state();
1151 self.skip();
1152 Ok((Event::SequenceEnd, mark))
1153 }
1154 Token(mark, TokenType::Key) => {
1155 self.state = State::FlowSequenceEntryMappingKey;
1156 self.skip();
1157 Ok((Event::MappingStart(0, None), mark))
1158 }
1159 _ => {
1160 self.push_state(State::FlowSequenceEntry);
1161 self.parse_node(false, false)
1162 }
1163 }
1164 }
1165
1166 fn indentless_sequence_entry<'a>(&mut self) -> ParseResult<'a>
1167 where
1168 'input: 'a,
1169 {
1170 match *self.peek_token()? {
1171 Token(mark, TokenType::BlockEntry) => {
1172 self.skip();
1173 if let Token(
1174 _,
1175 TokenType::BlockEntry | TokenType::Key | TokenType::Value | TokenType::BlockEnd,
1176 ) = *self.peek_token()?
1177 {
1178 self.state = State::IndentlessSequenceEntry;
1179 Ok((Event::empty_scalar(), mark))
1180 } else {
1181 self.push_state(State::IndentlessSequenceEntry);
1182 self.parse_node(true, false)
1183 }
1184 }
1185 Token(mark, _) => {
1186 self.pop_state();
1187 Ok((Event::SequenceEnd, mark))
1188 }
1189 }
1190 }
1191
1192 fn block_sequence_entry<'a>(&mut self, first: bool) -> ParseResult<'a>
1193 where
1194 'input: 'a,
1195 {
1196 if first {
1198 let _ = self.peek_token()?;
1199 self.skip();
1201 }
1202 match *self.peek_token()? {
1203 Token(mark, TokenType::BlockEnd) => {
1204 self.pop_state();
1205 self.skip();
1206 Ok((Event::SequenceEnd, mark))
1207 }
1208 Token(mark, TokenType::BlockEntry) => {
1209 self.skip();
1210 if let Token(_, TokenType::BlockEntry | TokenType::BlockEnd) = *self.peek_token()? {
1211 self.state = State::BlockSequenceEntry;
1212 Ok((Event::empty_scalar(), mark))
1213 } else {
1214 self.push_state(State::BlockSequenceEntry);
1215 self.parse_node(true, false)
1216 }
1217 }
1218 Token(span, _) => Err(ScanError::new_str(
1219 span.start,
1220 "while parsing a block collection, did not find expected '-' indicator",
1221 )),
1222 }
1223 }
1224
1225 fn flow_sequence_entry_mapping_key<'a>(&mut self) -> ParseResult<'a>
1226 where
1227 'input: 'a,
1228 {
1229 if let Token(mark, TokenType::Value | TokenType::FlowEntry | TokenType::FlowSequenceEnd) =
1230 *self.peek_token()?
1231 {
1232 self.skip();
1233 self.state = State::FlowSequenceEntryMappingValue;
1234 Ok((Event::empty_scalar(), mark))
1235 } else {
1236 self.push_state(State::FlowSequenceEntryMappingValue);
1237 self.parse_node(false, false)
1238 }
1239 }
1240
1241 fn flow_sequence_entry_mapping_value<'a>(&mut self) -> ParseResult<'a>
1242 where
1243 'input: 'a,
1244 {
1245 match *self.peek_token()? {
1246 Token(_, TokenType::Value) => {
1247 self.skip();
1248 self.state = State::FlowSequenceEntryMappingValue;
1249 let Token(span, ref tok) = *self.peek_token()?;
1250 if matches!(tok, TokenType::FlowEntry | TokenType::FlowSequenceEnd) {
1251 self.state = State::FlowSequenceEntryMappingEnd(span.end);
1252 Ok((Event::empty_scalar(), span))
1253 } else {
1254 self.push_state(State::FlowSequenceEntryMappingEnd(span.end));
1255 self.parse_node(false, false)
1256 }
1257 }
1258 Token(mark, _) => {
1259 self.state = State::FlowSequenceEntryMappingEnd(mark.end);
1260 Ok((Event::empty_scalar(), mark))
1261 }
1262 }
1263 }
1264
1265 #[allow(clippy::unnecessary_wraps)]
1266 fn flow_sequence_entry_mapping_end<'a>(&mut self, mark: Marker) -> ParseResult<'a>
1267 where
1268 'input: 'a,
1269 {
1270 self.state = State::FlowSequenceEntry;
1271 Ok((Event::MappingEnd, Span::empty(mark)))
1272 }
1273
1274 fn resolve_tag(
1276 &self,
1277 span: Span,
1278 handle: &str,
1279 suffix: String,
1280 ) -> Result<Cow<'input, Tag>, ScanError> {
1281 let tag = if handle == "!!" {
1282 Tag {
1285 handle: self
1286 .tags
1287 .get("!!")
1288 .map_or_else(|| "tag:yaml.org,2002:".to_string(), ToString::to_string),
1289 suffix,
1290 }
1291 } else if handle.is_empty() && suffix == "!" {
1292 match self.tags.get("") {
1294 Some(prefix) => Tag {
1295 handle: prefix.clone(),
1296 suffix,
1297 },
1298 None => Tag {
1299 handle: String::new(),
1300 suffix,
1301 },
1302 }
1303 } else {
1304 let prefix = self.tags.get(handle);
1306 if let Some(prefix) = prefix {
1307 Tag {
1308 handle: prefix.clone(),
1309 suffix,
1310 }
1311 } else {
1312 if handle.len() >= 2 && handle.starts_with('!') && handle.ends_with('!') {
1317 return Err(ScanError::new_str(span.start, "the handle wasn't declared"));
1318 }
1319 Tag {
1320 handle: handle.to_string(),
1321 suffix,
1322 }
1323 }
1324 };
1325 Ok(Cow::Owned(tag))
1326 }
1327}
1328
1329impl<'input, T: Input> Iterator for Parser<'input, T> {
1330 type Item = Result<(Event<'input>, Span), ScanError>;
1331
1332 fn next(&mut self) -> Option<Self::Item> {
1333 self.next_event()
1334 }
1335}
1336
1337#[cfg(test)]
1338mod test {
1339 use super::{Event, Parser};
1340
1341 #[test]
1342 fn test_peek_eq_parse() {
1343 let s = "
1344a0 bb: val
1345a1: &x
1346 b1: 4
1347 b2: d
1348a2: 4
1349a3: [1, 2, 3]
1350a4:
1351 - [a1, a2]
1352 - 2
1353a5: *x
1354";
1355 let mut p = Parser::new_from_str(s);
1356 loop {
1357 let event_peek = p.peek().unwrap().unwrap().clone();
1358 let event = p.next_event().unwrap().unwrap();
1359 assert_eq!(event, event_peek);
1360 if event.0 == Event::StreamEnd {
1361 break;
1362 }
1363 }
1364 }
1365
1366 #[test]
1367 fn test_keep_tags_across_multiple_documents() {
1368 let text = r#"
1369%YAML 1.1
1370%TAG !t! tag:test,2024:
1371--- !t!1 &1
1372foo: "bar"
1373--- !t!2 &2
1374baz: "qux"
1375"#;
1376 for x in Parser::new_from_str(text).keep_tags(true) {
1377 let x = x.unwrap();
1378 if let Event::MappingStart(_, tag) = x.0 {
1379 let tag = tag.unwrap();
1380 assert_eq!(tag.handle, "tag:test,2024:");
1381 }
1382 }
1383
1384 for x in Parser::new_from_str(text).keep_tags(false) {
1385 if x.is_err() {
1386 return;
1388 }
1389 }
1390 panic!("Test failed, did not encounter error")
1391 }
1392}