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