1use crate::{
8 input::{str::StrInput, Input},
9 scanner::{ScalarStyle, ScanError, Scanner, Span, Token, TokenType},
10 BufferedInput, Marker,
11};
12
13use std::{borrow::Cow, collections::HashMap, fmt::Display};
14
15#[derive(Clone, Copy, PartialEq, Debug, Eq)]
16enum State {
17 StreamStart,
18 ImplicitDocumentStart,
19 DocumentStart,
20 DocumentContent,
21 DocumentEnd,
22 BlockNode,
23 BlockSequenceFirstEntry,
24 BlockSequenceEntry,
25 IndentlessSequenceEntry,
26 BlockMappingFirstKey,
27 BlockMappingKey,
28 BlockMappingValue,
29 FlowSequenceFirstEntry,
30 FlowSequenceEntry,
31 FlowSequenceEntryMappingKey,
32 FlowSequenceEntryMappingValue,
33 FlowSequenceEntryMappingEnd(Marker),
34 FlowMappingFirstKey,
35 FlowMappingKey,
36 FlowMappingValue,
37 FlowMappingEmptyValue,
38 End,
39}
40
41#[derive(Clone, PartialEq, Debug, Eq)]
46pub enum Event<'input> {
47 Nothing,
49 StreamStart,
51 StreamEnd,
53 DocumentStart(bool),
61 DocumentEnd,
63 Alias(
65 usize,
67 ),
68 Scalar(
70 Cow<'input, str>,
71 ScalarStyle,
72 usize,
73 Option<Cow<'input, Tag>>,
74 ),
75 SequenceStart(
77 usize,
79 Option<Cow<'input, Tag>>,
81 ),
82 SequenceEnd,
84 MappingStart(
86 usize,
88 Option<Cow<'input, Tag>>,
90 ),
91 MappingEnd,
93}
94
95#[derive(Clone, PartialEq, Debug, Eq, Ord, PartialOrd, Hash)]
97pub struct Tag {
98 pub handle: String,
100 pub suffix: String,
102}
103
104impl Tag {
105 #[must_use]
114 pub fn is_yaml_core_schema(&self) -> bool {
115 self.handle == "tag:yaml.org,2002:"
116 }
117}
118
119impl Display for Tag {
120 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
121 write!(f, "{}!{}", self.handle, self.suffix)
122 }
123}
124
125impl<'input> Event<'input> {
126 fn empty_scalar() -> Self {
128 Event::Scalar("~".into(), ScalarStyle::Plain, 0, None)
130 }
131
132 fn empty_scalar_with_anchor(anchor: usize, tag: Option<Cow<'input, Tag>>) -> Self {
134 Event::Scalar(Cow::default(), ScalarStyle::Plain, anchor, tag)
135 }
136}
137
138#[derive(Debug)]
140pub struct Parser<'input, T: Input> {
141 scanner: Scanner<'input, T>,
143 states: Vec<State>,
148 state: State,
150 token: Option<Token<'input>>,
152 current: Option<(Event<'input>, Span)>,
154 anchors: HashMap<Cow<'input, str>, usize>,
156 anchor_id_count: usize,
161 tags: HashMap<String, String>,
165 stream_end_emitted: bool,
170 keep_tags: bool,
172}
173
174pub trait EventReceiver<'input> {
244 fn on_event(&mut self, ev: Event<'input>);
246}
247
248pub trait SpannedEventReceiver<'input> {
252 fn on_event(&mut self, ev: Event<'input>, span: Span);
254}
255
256impl<'input, R: EventReceiver<'input>> SpannedEventReceiver<'input> for R {
257 fn on_event(&mut self, ev: Event<'input>, _span: Span) {
258 self.on_event(ev);
259 }
260}
261
262pub type ParseResult<'input> = Result<(Event<'input>, Span), ScanError>;
264
265impl<'input> Parser<'input, StrInput<'input>> {
266 #[must_use]
268 pub fn new_from_str(value: &'input str) -> Self {
269 debug_print!("\x1B[;31m>>>>>>>>>> New parser from str\x1B[;0m");
270 Parser::new(StrInput::new(value))
271 }
272}
273
274impl<'input, T> Parser<'input, BufferedInput<T>>
275where
276 T: Iterator<Item = char> + 'input,
277{
278 #[must_use]
280 pub fn new_from_iter(iter: T) -> Self {
281 debug_print!("\x1B[;31m>>>>>>>>>> New parser from iter\x1B[;0m");
282 Parser::new(BufferedInput::new(iter))
283 }
284}
285
286impl<'input, T: Input> Parser<'input, T> {
287 pub fn new(src: T) -> Self {
289 Parser {
290 scanner: Scanner::new(src),
291 states: Vec::new(),
292 state: State::StreamStart,
293 token: None,
294 current: None,
295
296 anchors: HashMap::new(),
297 anchor_id_count: 1,
299 tags: HashMap::new(),
300 stream_end_emitted: false,
301 keep_tags: false,
302 }
303 }
304
305 #[must_use]
328 pub fn keep_tags(mut self, value: bool) -> Self {
329 self.keep_tags = value;
330 self
331 }
332
333 pub fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
341 if let Some(ref x) = self.current {
342 Some(Ok(x))
343 } else {
344 if self.stream_end_emitted {
345 return None;
346 }
347 match self.next_event_impl() {
348 Ok(token) => self.current = Some(token),
349 Err(e) => return Some(Err(e)),
350 }
351 self.current.as_ref().map(Ok)
352 }
353 }
354
355 pub fn next_event(&mut self) -> Option<ParseResult<'input>> {
360 if self.stream_end_emitted {
361 return None;
362 }
363
364 let tok = self.next_event_impl();
365 if matches!(tok, Ok((Event::StreamEnd, _))) {
366 self.stream_end_emitted = true;
367 }
368 Some(tok)
369 }
370
371 fn next_event_impl<'a>(&mut self) -> ParseResult<'a>
377 where
378 'input: 'a,
379 {
380 match self.current.take() {
381 None => self.parse(),
382 Some(v) => Ok(v),
383 }
384 }
385
386 fn peek_token(&mut self) -> Result<&Token, ScanError> {
388 match self.token {
389 None => {
390 self.token = Some(self.scan_next_token()?);
391 Ok(self.token.as_ref().unwrap())
392 }
393 Some(ref tok) => Ok(tok),
394 }
395 }
396
397 fn scan_next_token(&mut self) -> Result<Token<'input>, ScanError> {
401 let token = self.scanner.next();
402 match token {
403 None => match self.scanner.get_error() {
404 None => Err(ScanError::new_str(self.scanner.mark(), "unexpected eof")),
405 Some(e) => Err(e),
406 },
407 Some(tok) => Ok(tok),
408 }
409 }
410
411 fn fetch_token<'a>(&mut self) -> Token<'a>
412 where
413 'input: 'a,
414 {
415 self.token
416 .take()
417 .expect("fetch_token needs to be preceded by peek_token")
418 }
419
420 fn skip(&mut self) {
422 self.token = None;
423 }
424 fn pop_state(&mut self) {
426 self.state = self.states.pop().unwrap();
427 }
428 fn push_state(&mut self, state: State) {
430 self.states.push(state);
431 }
432
433 fn parse<'a>(&mut self) -> ParseResult<'a>
434 where
435 'input: 'a,
436 {
437 if self.state == State::End {
438 return Ok((Event::StreamEnd, Span::empty(self.scanner.mark())));
439 }
440 let (ev, mark) = self.state_machine()?;
441 Ok((ev, mark))
442 }
443
444 pub fn load<R: SpannedEventReceiver<'input>>(
457 &mut self,
458 recv: &mut R,
459 multi: bool,
460 ) -> Result<(), ScanError> {
461 if !self.scanner.stream_started() {
462 let (ev, span) = self.next_event_impl()?;
463 if ev != Event::StreamStart {
464 return Err(ScanError::new_str(
465 span.start,
466 "did not find expected <stream-start>",
467 ));
468 }
469 recv.on_event(ev, span);
470 }
471
472 if self.scanner.stream_ended() {
473 recv.on_event(Event::StreamEnd, Span::empty(self.scanner.mark()));
475 return Ok(());
476 }
477 loop {
478 let (ev, span) = self.next_event_impl()?;
479 if ev == Event::StreamEnd {
480 recv.on_event(ev, span);
481 return Ok(());
482 }
483 self.anchors.clear();
485 self.load_document(ev, span, recv)?;
486 if !multi {
487 break;
488 }
489 }
490 Ok(())
491 }
492
493 fn load_document<R: SpannedEventReceiver<'input>>(
494 &mut self,
495 first_ev: Event<'input>,
496 span: Span,
497 recv: &mut R,
498 ) -> Result<(), ScanError> {
499 if !matches!(first_ev, Event::DocumentStart(_)) {
500 return Err(ScanError::new_str(
501 span.start,
502 "did not find expected <document-start>",
503 ));
504 }
505 recv.on_event(first_ev, span);
506
507 let (ev, span) = self.next_event_impl()?;
508 self.load_node(ev, span, recv)?;
509
510 let (ev, mark) = self.next_event_impl()?;
512 assert_eq!(ev, Event::DocumentEnd);
513 recv.on_event(ev, mark);
514
515 Ok(())
516 }
517
518 fn load_node<R: SpannedEventReceiver<'input>>(
519 &mut self,
520 first_ev: Event<'input>,
521 span: Span,
522 recv: &mut R,
523 ) -> Result<(), ScanError> {
524 match first_ev {
525 Event::Alias(..) | Event::Scalar(..) => {
526 recv.on_event(first_ev, span);
527 Ok(())
528 }
529 Event::SequenceStart(..) => {
530 recv.on_event(first_ev, span);
531 self.load_sequence(recv)
532 }
533 Event::MappingStart(..) => {
534 recv.on_event(first_ev, span);
535 self.load_mapping(recv)
536 }
537 _ => {
538 println!("UNREACHABLE EVENT: {first_ev:?}");
539 unreachable!();
540 }
541 }
542 }
543
544 fn load_mapping<R: SpannedEventReceiver<'input>>(
545 &mut self,
546 recv: &mut R,
547 ) -> Result<(), ScanError> {
548 let (mut key_ev, mut key_mark) = self.next_event_impl()?;
549 while key_ev != Event::MappingEnd {
550 self.load_node(key_ev, key_mark, recv)?;
552
553 let (ev, mark) = self.next_event_impl()?;
555 self.load_node(ev, mark, recv)?;
556
557 let (ev, mark) = self.next_event_impl()?;
559 key_ev = ev;
560 key_mark = mark;
561 }
562 recv.on_event(key_ev, key_mark);
563 Ok(())
564 }
565
566 fn load_sequence<R: SpannedEventReceiver<'input>>(
567 &mut self,
568 recv: &mut R,
569 ) -> Result<(), ScanError> {
570 let (mut ev, mut mark) = self.next_event_impl()?;
571 while ev != Event::SequenceEnd {
572 self.load_node(ev, mark, recv)?;
573
574 let (next_ev, next_mark) = self.next_event_impl()?;
576 ev = next_ev;
577 mark = next_mark;
578 }
579 recv.on_event(ev, mark);
580 Ok(())
581 }
582
583 fn state_machine<'a>(&mut self) -> ParseResult<'a>
584 where
585 'input: 'a,
586 {
587 debug_print!("\n\x1B[;33mParser state: {:?} \x1B[;0m", self.state);
590
591 match self.state {
592 State::StreamStart => self.stream_start(),
593
594 State::ImplicitDocumentStart => self.document_start(true),
595 State::DocumentStart => self.document_start(false),
596 State::DocumentContent => self.document_content(),
597 State::DocumentEnd => self.document_end(),
598
599 State::BlockNode => self.parse_node(true, false),
600 State::BlockMappingFirstKey => self.block_mapping_key(true),
603 State::BlockMappingKey => self.block_mapping_key(false),
604 State::BlockMappingValue => self.block_mapping_value(),
605
606 State::BlockSequenceFirstEntry => self.block_sequence_entry(true),
607 State::BlockSequenceEntry => self.block_sequence_entry(false),
608
609 State::FlowSequenceFirstEntry => self.flow_sequence_entry(true),
610 State::FlowSequenceEntry => self.flow_sequence_entry(false),
611
612 State::FlowMappingFirstKey => self.flow_mapping_key(true),
613 State::FlowMappingKey => self.flow_mapping_key(false),
614 State::FlowMappingValue => self.flow_mapping_value(false),
615
616 State::IndentlessSequenceEntry => self.indentless_sequence_entry(),
617
618 State::FlowSequenceEntryMappingKey => self.flow_sequence_entry_mapping_key(),
619 State::FlowSequenceEntryMappingValue => self.flow_sequence_entry_mapping_value(),
620 State::FlowSequenceEntryMappingEnd(mark) => self.flow_sequence_entry_mapping_end(mark),
621 State::FlowMappingEmptyValue => self.flow_mapping_value(true),
622
623 State::End => unreachable!(),
625 }
626 }
627
628 fn stream_start<'a>(&mut self) -> ParseResult<'a>
629 where
630 'input: 'a,
631 {
632 match *self.peek_token()? {
633 Token(span, TokenType::StreamStart(_)) => {
634 self.state = State::ImplicitDocumentStart;
635 self.skip();
636 Ok((Event::StreamStart, span))
637 }
638 Token(span, _) => Err(ScanError::new_str(
639 span.start,
640 "did not find expected <stream-start>",
641 )),
642 }
643 }
644
645 fn document_start<'a>(&mut self, implicit: bool) -> ParseResult<'a>
646 where
647 'input: 'a,
648 {
649 while let TokenType::DocumentEnd = self.peek_token()?.1 {
650 self.skip();
651 }
652
653 match *self.peek_token()? {
654 Token(span, TokenType::StreamEnd) => {
655 self.state = State::End;
656 self.skip();
657 Ok((Event::StreamEnd, span))
658 }
659 Token(
660 _,
661 TokenType::VersionDirective(..)
662 | TokenType::TagDirective(..)
663 | TokenType::DocumentStart,
664 ) => {
665 self.explicit_document_start()
667 }
668 Token(span, _) if implicit => {
669 self.parser_process_directives()?;
670 self.push_state(State::DocumentEnd);
671 self.state = State::BlockNode;
672 Ok((Event::DocumentStart(false), span))
673 }
674 _ => {
675 self.explicit_document_start()
677 }
678 }
679 }
680
681 fn parser_process_directives(&mut self) -> Result<(), ScanError> {
682 let mut version_directive_received = false;
683 loop {
684 let mut tags = HashMap::new();
685 match self.peek_token()? {
686 Token(span, TokenType::VersionDirective(_, _)) => {
687 if version_directive_received {
693 return Err(ScanError::new_str(
694 span.start,
695 "duplicate version directive",
696 ));
697 }
698 version_directive_received = true;
699 }
700 Token(mark, TokenType::TagDirective(handle, prefix)) => {
701 if tags.contains_key(&**handle) {
702 return Err(ScanError::new_str(mark.start, "the TAG directive must only be given at most once per handle in the same document"));
703 }
704 tags.insert(handle.to_string(), prefix.to_string());
705 }
706 _ => break,
707 }
708 self.tags = tags;
709 self.skip();
710 }
711 Ok(())
712 }
713
714 fn explicit_document_start<'a>(&mut self) -> ParseResult<'a>
715 where
716 'input: 'a,
717 {
718 self.parser_process_directives()?;
719 match *self.peek_token()? {
720 Token(mark, TokenType::DocumentStart) => {
721 self.push_state(State::DocumentEnd);
722 self.state = State::DocumentContent;
723 self.skip();
724 Ok((Event::DocumentStart(true), mark))
725 }
726 Token(span, _) => Err(ScanError::new_str(
727 span.start,
728 "did not find expected <document start>",
729 )),
730 }
731 }
732
733 fn document_content<'a>(&mut self) -> ParseResult<'a>
734 where
735 'input: 'a,
736 {
737 match *self.peek_token()? {
738 Token(
739 mark,
740 TokenType::VersionDirective(..)
741 | TokenType::TagDirective(..)
742 | TokenType::DocumentStart
743 | TokenType::DocumentEnd
744 | TokenType::StreamEnd,
745 ) => {
746 self.pop_state();
747 Ok((Event::empty_scalar(), mark))
749 }
750 _ => self.parse_node(true, false),
751 }
752 }
753
754 fn document_end<'a>(&mut self) -> ParseResult<'a>
755 where
756 'input: 'a,
757 {
758 let mut explicit_end = false;
759 let span: Span = match *self.peek_token()? {
760 Token(span, TokenType::DocumentEnd) => {
761 explicit_end = true;
762 self.skip();
763 span
764 }
765 Token(span, _) => span,
766 };
767
768 if !self.keep_tags {
769 self.tags.clear();
770 }
771 if explicit_end {
772 self.state = State::ImplicitDocumentStart;
773 } else {
774 if let Token(span, TokenType::VersionDirective(..) | TokenType::TagDirective(..)) =
775 *self.peek_token()?
776 {
777 return Err(ScanError::new_str(
778 span.start,
779 "missing explicit document end marker before directive",
780 ));
781 }
782 self.state = State::DocumentStart;
783 }
784
785 Ok((Event::DocumentEnd, span))
786 }
787
788 fn register_anchor(&mut self, name: Cow<'input, str>, _: &Span) -> usize {
789 let new_id = self.anchor_id_count;
795 self.anchor_id_count += 1;
796 self.anchors.insert(name, new_id);
797 new_id
798 }
799
800 fn parse_node<'a>(&mut self, block: bool, indentless_sequence: bool) -> ParseResult<'a>
801 where
802 'input: 'a,
803 {
804 let mut anchor_id = 0;
805 let mut tag = None;
806 match *self.peek_token()? {
807 Token(_, TokenType::Alias(_)) => {
808 self.pop_state();
809 if let Token(span, TokenType::Alias(name)) = self.fetch_token() {
810 match self.anchors.get(&*name) {
811 None => {
812 return Err(ScanError::new_str(
813 span.start,
814 "while parsing node, found unknown anchor",
815 ))
816 }
817 Some(id) => return Ok((Event::Alias(*id), span)),
818 }
819 }
820 unreachable!()
821 }
822 Token(_, TokenType::Anchor(_)) => {
823 if let Token(span, TokenType::Anchor(name)) = self.fetch_token() {
824 anchor_id = self.register_anchor(name, &span);
825 if let TokenType::Tag(..) = self.peek_token()?.1 {
826 if let TokenType::Tag(handle, suffix) = self.fetch_token().1 {
827 tag = Some(self.resolve_tag(span, &handle, suffix)?);
828 } else {
829 unreachable!()
830 }
831 }
832 } else {
833 unreachable!()
834 }
835 }
836 Token(mark, TokenType::Tag(..)) => {
837 if let TokenType::Tag(handle, suffix) = self.fetch_token().1 {
838 tag = Some(self.resolve_tag(mark, &handle, suffix)?);
839 if let TokenType::Anchor(_) = &self.peek_token()?.1 {
840 if let Token(mark, TokenType::Anchor(name)) = self.fetch_token() {
841 anchor_id = self.register_anchor(name, &mark);
842 } else {
843 unreachable!()
844 }
845 }
846 } else {
847 unreachable!()
848 }
849 }
850 _ => {}
851 }
852 match *self.peek_token()? {
853 Token(mark, TokenType::BlockEntry) if indentless_sequence => {
854 self.state = State::IndentlessSequenceEntry;
855 Ok((Event::SequenceStart(anchor_id, tag), mark))
856 }
857 Token(_, TokenType::Scalar(..)) => {
858 self.pop_state();
859 if let Token(mark, TokenType::Scalar(style, v)) = self.fetch_token() {
860 Ok((Event::Scalar(v, style, anchor_id, tag), mark))
861 } else {
862 unreachable!()
863 }
864 }
865 Token(mark, TokenType::FlowSequenceStart) => {
866 self.state = State::FlowSequenceFirstEntry;
867 Ok((Event::SequenceStart(anchor_id, tag), mark))
868 }
869 Token(mark, TokenType::FlowMappingStart) => {
870 self.state = State::FlowMappingFirstKey;
871 Ok((Event::MappingStart(anchor_id, tag), mark))
872 }
873 Token(mark, TokenType::BlockSequenceStart) if block => {
874 self.state = State::BlockSequenceFirstEntry;
875 Ok((Event::SequenceStart(anchor_id, tag), mark))
876 }
877 Token(mark, TokenType::BlockMappingStart) if block => {
878 self.state = State::BlockMappingFirstKey;
879 Ok((Event::MappingStart(anchor_id, tag), mark))
880 }
881 Token(mark, _) if tag.is_some() || anchor_id > 0 => {
883 self.pop_state();
884 Ok((Event::empty_scalar_with_anchor(anchor_id, tag), mark))
885 }
886 Token(span, _) => Err(ScanError::new_str(
887 span.start,
888 "while parsing a node, did not find expected node content",
889 )),
890 }
891 }
892
893 fn block_mapping_key<'a>(&mut self, first: bool) -> ParseResult<'a>
894 where
895 'input: 'a,
896 {
897 if first {
899 let _ = self.peek_token()?;
900 self.skip();
902 }
903 match *self.peek_token()? {
904 Token(_, TokenType::Key) => {
905 self.skip();
906 if let Token(mark, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
907 *self.peek_token()?
908 {
909 self.state = State::BlockMappingValue;
910 Ok((Event::empty_scalar(), mark))
912 } else {
913 self.push_state(State::BlockMappingValue);
914 self.parse_node(true, true)
915 }
916 }
917 Token(mark, TokenType::Value) => {
919 self.state = State::BlockMappingValue;
920 Ok((Event::empty_scalar(), mark))
921 }
922 Token(mark, TokenType::BlockEnd) => {
923 self.pop_state();
924 self.skip();
925 Ok((Event::MappingEnd, mark))
926 }
927 Token(span, _) => Err(ScanError::new_str(
928 span.start,
929 "while parsing a block mapping, did not find expected key",
930 )),
931 }
932 }
933
934 fn block_mapping_value<'a>(&mut self) -> ParseResult<'a>
935 where
936 'input: 'a,
937 {
938 match *self.peek_token()? {
939 Token(mark, TokenType::Value) => {
940 self.skip();
941 if let Token(_, TokenType::Key | TokenType::Value | TokenType::BlockEnd) =
942 *self.peek_token()?
943 {
944 self.state = State::BlockMappingKey;
945 Ok((Event::empty_scalar(), mark))
947 } else {
948 self.push_state(State::BlockMappingKey);
949 self.parse_node(true, true)
950 }
951 }
952 Token(mark, _) => {
953 self.state = State::BlockMappingKey;
954 Ok((Event::empty_scalar(), mark))
956 }
957 }
958 }
959
960 fn flow_mapping_key<'a>(&mut self, first: bool) -> ParseResult<'a>
961 where
962 'input: 'a,
963 {
964 if first {
965 let _ = self.peek_token()?;
966 self.skip();
967 }
968 let span: Span = {
969 match *self.peek_token()? {
970 Token(mark, TokenType::FlowMappingEnd) => mark,
971 Token(mark, _) => {
972 if !first {
973 match *self.peek_token()? {
974 Token(_, TokenType::FlowEntry) => self.skip(),
975 Token(span, _) => return Err(ScanError::new_str(
976 span.start,
977 "while parsing a flow mapping, did not find expected ',' or '}'",
978 )),
979 }
980 }
981
982 match *self.peek_token()? {
983 Token(_, TokenType::Key) => {
984 self.skip();
985 if let Token(
986 mark,
987 TokenType::Value | TokenType::FlowEntry | TokenType::FlowMappingEnd,
988 ) = *self.peek_token()?
989 {
990 self.state = State::FlowMappingValue;
991 return Ok((Event::empty_scalar(), mark));
992 }
993 self.push_state(State::FlowMappingValue);
994 return self.parse_node(false, false);
995 }
996 Token(marker, TokenType::Value) => {
997 self.state = State::FlowMappingValue;
998 return Ok((Event::empty_scalar(), marker));
999 }
1000 Token(_, TokenType::FlowMappingEnd) => (),
1001 _ => {
1002 self.push_state(State::FlowMappingEmptyValue);
1003 return self.parse_node(false, false);
1004 }
1005 }
1006
1007 mark
1008 }
1009 }
1010 };
1011
1012 self.pop_state();
1013 self.skip();
1014 Ok((Event::MappingEnd, span))
1015 }
1016
1017 fn flow_mapping_value<'a>(&mut self, empty: bool) -> ParseResult<'a>
1018 where
1019 'input: 'a,
1020 {
1021 let span: Span = {
1022 if empty {
1023 let Token(mark, _) = *self.peek_token()?;
1024 self.state = State::FlowMappingKey;
1025 return Ok((Event::empty_scalar(), mark));
1026 }
1027 match *self.peek_token()? {
1028 Token(span, TokenType::Value) => {
1029 self.skip();
1030 match self.peek_token()?.1 {
1031 TokenType::FlowEntry | TokenType::FlowMappingEnd => {}
1032 _ => {
1033 self.push_state(State::FlowMappingKey);
1034 return self.parse_node(false, false);
1035 }
1036 }
1037 span
1038 }
1039 Token(marker, _) => marker,
1040 }
1041 };
1042
1043 self.state = State::FlowMappingKey;
1044 Ok((Event::empty_scalar(), span))
1045 }
1046
1047 fn flow_sequence_entry<'a>(&mut self, first: bool) -> ParseResult<'a>
1048 where
1049 'input: 'a,
1050 {
1051 if first {
1053 let _ = self.peek_token()?;
1054 self.skip();
1056 }
1057 match *self.peek_token()? {
1058 Token(mark, TokenType::FlowSequenceEnd) => {
1059 self.pop_state();
1060 self.skip();
1061 return Ok((Event::SequenceEnd, mark));
1062 }
1063 Token(_, TokenType::FlowEntry) if !first => {
1064 self.skip();
1065 }
1066 Token(span, _) if !first => {
1067 return Err(ScanError::new_str(
1068 span.start,
1069 "while parsing a flow sequence, expected ',' or ']'",
1070 ));
1071 }
1072 _ => { }
1073 }
1074 match *self.peek_token()? {
1075 Token(mark, TokenType::FlowSequenceEnd) => {
1076 self.pop_state();
1077 self.skip();
1078 Ok((Event::SequenceEnd, mark))
1079 }
1080 Token(mark, TokenType::Key) => {
1081 self.state = State::FlowSequenceEntryMappingKey;
1082 self.skip();
1083 Ok((Event::MappingStart(0, None), mark))
1084 }
1085 _ => {
1086 self.push_state(State::FlowSequenceEntry);
1087 self.parse_node(false, false)
1088 }
1089 }
1090 }
1091
1092 fn indentless_sequence_entry<'a>(&mut self) -> ParseResult<'a>
1093 where
1094 'input: 'a,
1095 {
1096 match *self.peek_token()? {
1097 Token(mark, TokenType::BlockEntry) => {
1098 self.skip();
1099 if let Token(
1100 _,
1101 TokenType::BlockEntry | TokenType::Key | TokenType::Value | TokenType::BlockEnd,
1102 ) = *self.peek_token()?
1103 {
1104 self.state = State::IndentlessSequenceEntry;
1105 Ok((Event::empty_scalar(), mark))
1106 } else {
1107 self.push_state(State::IndentlessSequenceEntry);
1108 self.parse_node(true, false)
1109 }
1110 }
1111 Token(mark, _) => {
1112 self.pop_state();
1113 Ok((Event::SequenceEnd, mark))
1114 }
1115 }
1116 }
1117
1118 fn block_sequence_entry<'a>(&mut self, first: bool) -> ParseResult<'a>
1119 where
1120 'input: 'a,
1121 {
1122 if first {
1124 let _ = self.peek_token()?;
1125 self.skip();
1127 }
1128 match *self.peek_token()? {
1129 Token(mark, TokenType::BlockEnd) => {
1130 self.pop_state();
1131 self.skip();
1132 Ok((Event::SequenceEnd, mark))
1133 }
1134 Token(mark, TokenType::BlockEntry) => {
1135 self.skip();
1136 if let Token(_, TokenType::BlockEntry | TokenType::BlockEnd) = *self.peek_token()? {
1137 self.state = State::BlockSequenceEntry;
1138 Ok((Event::empty_scalar(), mark))
1139 } else {
1140 self.push_state(State::BlockSequenceEntry);
1141 self.parse_node(true, false)
1142 }
1143 }
1144 Token(span, _) => Err(ScanError::new_str(
1145 span.start,
1146 "while parsing a block collection, did not find expected '-' indicator",
1147 )),
1148 }
1149 }
1150
1151 fn flow_sequence_entry_mapping_key<'a>(&mut self) -> ParseResult<'a>
1152 where
1153 'input: 'a,
1154 {
1155 if let Token(mark, TokenType::Value | TokenType::FlowEntry | TokenType::FlowSequenceEnd) =
1156 *self.peek_token()?
1157 {
1158 self.skip();
1159 self.state = State::FlowSequenceEntryMappingValue;
1160 Ok((Event::empty_scalar(), mark))
1161 } else {
1162 self.push_state(State::FlowSequenceEntryMappingValue);
1163 self.parse_node(false, false)
1164 }
1165 }
1166
1167 fn flow_sequence_entry_mapping_value<'a>(&mut self) -> ParseResult<'a>
1168 where
1169 'input: 'a,
1170 {
1171 match *self.peek_token()? {
1172 Token(_, TokenType::Value) => {
1173 self.skip();
1174 self.state = State::FlowSequenceEntryMappingValue;
1175 let Token(span, ref tok) = *self.peek_token()?;
1176 if matches!(tok, TokenType::FlowEntry | TokenType::FlowSequenceEnd) {
1177 self.state = State::FlowSequenceEntryMappingEnd(span.end);
1178 Ok((Event::empty_scalar(), span))
1179 } else {
1180 self.push_state(State::FlowSequenceEntryMappingEnd(span.end));
1181 self.parse_node(false, false)
1182 }
1183 }
1184 Token(mark, _) => {
1185 self.state = State::FlowSequenceEntryMappingEnd(mark.end);
1186 Ok((Event::empty_scalar(), mark))
1187 }
1188 }
1189 }
1190
1191 #[allow(clippy::unnecessary_wraps)]
1192 fn flow_sequence_entry_mapping_end<'a>(&mut self, mark: Marker) -> ParseResult<'a>
1193 where
1194 'input: 'a,
1195 {
1196 self.state = State::FlowSequenceEntry;
1197 Ok((Event::MappingEnd, Span::empty(mark)))
1198 }
1199
1200 fn resolve_tag(
1202 &self,
1203 span: Span,
1204 handle: &str,
1205 suffix: String,
1206 ) -> Result<Cow<'input, Tag>, ScanError> {
1207 let tag = if handle == "!!" {
1208 Tag {
1211 handle: self
1212 .tags
1213 .get("!!")
1214 .map_or_else(|| "tag:yaml.org,2002:".to_string(), ToString::to_string),
1215 suffix,
1216 }
1217 } else if handle.is_empty() && suffix == "!" {
1218 match self.tags.get("") {
1220 Some(prefix) => Tag {
1221 handle: prefix.to_string(),
1222 suffix,
1223 },
1224 None => Tag {
1225 handle: String::new(),
1226 suffix,
1227 },
1228 }
1229 } else {
1230 let prefix = self.tags.get(handle);
1232 if let Some(prefix) = prefix {
1233 Tag {
1234 handle: prefix.to_string(),
1235 suffix,
1236 }
1237 } else {
1238 if handle.len() >= 2 && handle.starts_with('!') && handle.ends_with('!') {
1243 return Err(ScanError::new_str(span.start, "the handle wasn't declared"));
1244 }
1245 Tag {
1246 handle: handle.to_string(),
1247 suffix,
1248 }
1249 }
1250 };
1251 Ok(Cow::Owned(tag))
1252 }
1253}
1254
1255impl<'input, T: Input> Iterator for Parser<'input, T> {
1256 type Item = Result<(Event<'input>, Span), ScanError>;
1257
1258 fn next(&mut self) -> Option<Self::Item> {
1259 self.next_event()
1260 }
1261}
1262
1263#[cfg(test)]
1264mod test {
1265 use super::{Event, Parser};
1266
1267 #[test]
1268 fn test_peek_eq_parse() {
1269 let s = "
1270a0 bb: val
1271a1: &x
1272 b1: 4
1273 b2: d
1274a2: 4
1275a3: [1, 2, 3]
1276a4:
1277 - [a1, a2]
1278 - 2
1279a5: *x
1280";
1281 let mut p = Parser::new_from_str(s);
1282 loop {
1283 let event_peek = p.peek().unwrap().unwrap().clone();
1284 let event = p.next_event().unwrap().unwrap();
1285 assert_eq!(event, event_peek);
1286 if event.0 == Event::StreamEnd {
1287 break;
1288 }
1289 }
1290 }
1291
1292 #[test]
1293 fn test_keep_tags_across_multiple_documents() {
1294 let text = r#"
1295%YAML 1.1
1296%TAG !t! tag:test,2024:
1297--- !t!1 &1
1298foo: "bar"
1299--- !t!2 &2
1300baz: "qux"
1301"#;
1302 for x in Parser::new_from_str(text).keep_tags(true) {
1303 let x = x.unwrap();
1304 if let Event::MappingStart(_, tag) = x.0 {
1305 let tag = tag.unwrap();
1306 assert_eq!(tag.handle, "tag:test,2024:");
1307 }
1308 }
1309
1310 for x in Parser::new_from_str(text).keep_tags(false) {
1311 if x.is_err() {
1312 return;
1314 }
1315 }
1316 panic!("Test failed, did not encounter error")
1317 }
1318}