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