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}