1use crate::{
2 error::{ErrorKind, ScanError},
3 input::{str::StrInput, BorrowedInput, BufferedInput},
4 parser::{Event, ParseResult, Parser, ParserTrait, SpannedEventReceiver},
5 scanner::Span,
6 Options,
7};
8use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
9
10pub struct ReplayParser<'input> {
12 events: alloc::vec::IntoIter<(Event<'input>, Span)>,
13 anchor_offset: usize,
14}
15
16impl<'input> ReplayParser<'input> {
17 #[must_use]
19 pub fn new(events: Vec<(Event<'input>, Span)>, anchor_offset: usize) -> Self {
20 Self {
21 events: events.into_iter(),
22 anchor_offset,
23 }
24 }
25
26 #[must_use]
28 pub fn anchor_offset(&self) -> usize {
29 self.anchor_offset
30 }
31
32 pub fn set_anchor_offset(&mut self, offset: usize) {
34 self.anchor_offset = offset;
35 }
36
37 fn advance_anchor_offset(&mut self, event: &Event<'input>) {
38 let anchor_id = match event {
39 Event::Scalar(_, _, anchor_id, _)
40 | Event::SequenceStart(_, anchor_id, _)
41 | Event::MappingStart(_, anchor_id, _) => *anchor_id,
42 _ => 0,
43 };
44
45 if anchor_id > 0 {
46 self.anchor_offset = self.anchor_offset.max(anchor_id.saturating_add(1));
47 }
48 }
49}
50
51impl<'input> ParserTrait<'input> for ReplayParser<'input> {
52 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
53 self.events.as_slice().first().map(Ok)
54 }
55
56 fn next_event(&mut self) -> Option<ParseResult<'input>> {
57 let event = self.events.next()?;
58 self.advance_anchor_offset(&event.0);
59 Some(Ok(event))
60 }
61
62 fn load<R: SpannedEventReceiver<'input>>(
63 &mut self,
64 recv: &mut R,
65 multi: bool,
66 ) -> Result<(), ScanError> {
67 while let Some(res) = self.next_event() {
68 let (ev, span) = res?;
69 let is_doc_end = matches!(ev, Event::DocumentEnd);
70 let is_stream_end = matches!(ev, Event::StreamEnd);
71 recv.on_event(ev, span);
72 if is_stream_end {
73 break;
74 }
75 if !multi && is_doc_end {
76 break;
77 }
78 }
79 Ok(())
80 }
81}
82
83impl<'input> Iterator for ReplayParser<'input> {
84 type Item = ParseResult<'input>;
85
86 fn next(&mut self) -> Option<Self::Item> {
87 self.next_event()
88 }
89}
90
91impl core::iter::FusedIterator for ReplayParser<'_> {}
92
93enum AnyParser<'input, I, T>
95where
96 I: Iterator<Item = char>,
97 T: BorrowedInput<'input>,
98{
99 String {
101 parser: Parser<'input, StrInput<'input>>,
103 name: String,
105 },
106 Iter {
108 parser: Parser<'static, BufferedInput<I>>,
110 name: String,
112 },
113 Custom {
115 parser: Parser<'input, T>,
117 name: String,
119 },
120 Replay {
122 parser: ReplayParser<'input>,
124 name: String,
126 },
127}
128
129impl<'input, I, T> AnyParser<'input, I, T>
130where
131 I: Iterator<Item = char>,
132 T: BorrowedInput<'input>,
133{
134 fn anchor_offset(&self) -> usize {
135 match self {
136 AnyParser::String { parser, .. } => parser.anchor_offset(),
137 AnyParser::Iter { parser, .. } => parser.anchor_offset(),
138 AnyParser::Custom { parser, .. } => parser.anchor_offset(),
139 AnyParser::Replay { parser, .. } => parser.anchor_offset(),
140 }
141 }
142
143 fn set_anchor_offset(&mut self, offset: usize) {
144 match self {
145 AnyParser::String { parser, .. } => parser.set_anchor_offset(offset),
146 AnyParser::Iter { parser, .. } => parser.set_anchor_offset(offset),
147 AnyParser::Custom { parser, .. } => parser.set_anchor_offset(offset),
148 AnyParser::Replay { parser, .. } => parser.set_anchor_offset(offset),
149 }
150 }
151}
152
153pub struct ParserStack<'input, I = core::iter::Empty<char>, T = StrInput<'input>>
169where
170 I: Iterator<Item = char>,
171 T: BorrowedInput<'input>,
172{
173 options: Options,
174 parsers: Vec<AnyParser<'input, I, T>>,
175 current: Option<(Event<'input>, Span)>,
176 current_error: Option<ScanError>,
177 stream_end_emitted: bool,
178 #[allow(clippy::type_complexity)]
179 include_resolver: Option<Box<dyn FnMut(&str) -> Result<Cow<'input, str>, ScanError> + 'input>>,
180}
181
182impl<'input, I, T> ParserStack<'input, I, T>
183where
184 I: Iterator<Item = char>,
185 T: BorrowedInput<'input>,
186{
187 #[must_use]
189 pub fn new() -> Self {
190 Self::with_options(Options::default())
191 }
192
193 #[must_use]
201 pub fn with_options(options: Options) -> Self {
202 Self {
203 options,
204 parsers: Vec::new(),
205 current: None,
206 current_error: None,
207 stream_end_emitted: false,
208 include_resolver: None,
209 }
210 }
211
212 pub fn set_resolver(
216 &mut self,
217 mut resolver: impl FnMut(&str) -> Result<String, ScanError> + 'input,
218 ) {
219 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Owned)));
220 }
221
222 pub fn set_borrowed_resolver(
228 &mut self,
229 mut resolver: impl FnMut(&str) -> Result<&'input str, ScanError> + 'input,
230 ) {
231 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Borrowed)));
232 }
233
234 pub fn push_include(&mut self, include_str: &str) -> Result<(), ScanError> {
244 let resolved = match &mut self.include_resolver {
245 Some(resolver) => resolver(include_str),
246 None => {
247 return Err(self.contextualize_include_error(
248 ScanError::from_kind(
249 crate::scanner::Marker::new(0, 1, 0),
250 ErrorKind::MissingIncludeResolver,
251 ),
252 include_str,
253 ));
254 }
255 };
256 let content = match resolved {
257 Ok(content) => content,
258 Err(error) => return Err(self.contextualize_include_error(error, include_str)),
259 };
260 let inherited_anchor_offset = self.parsers.last().map(AnyParser::anchor_offset);
261
262 let (events, next_anchor_offset) = match content {
263 Cow::Borrowed(content) => {
264 let mut parser = Parser::new_from_str_with_options(content, self.options.clone());
265 if let Some(anchor_offset) = inherited_anchor_offset {
266 parser.set_anchor_offset(anchor_offset);
267 }
268 let mut events = Vec::new();
269 while let Some(event) = parser.next_event() {
270 match event {
271 Ok(event) => events.push(event),
272 Err(error) => {
273 return Err(self.contextualize_include_error(error, include_str));
274 }
275 }
276 }
277 (events, parser.anchor_offset())
278 }
279 Cow::Owned(content) => {
280 let mut parser =
281 Parser::new_from_iter_with_options(content.chars(), self.options.clone());
282 if let Some(anchor_offset) = inherited_anchor_offset {
283 parser.set_anchor_offset(anchor_offset);
284 }
285 let mut events = Vec::new();
286 while let Some(event) = parser.next_event() {
287 match event {
288 Ok(event) => events.push(event),
289 Err(error) => {
290 return Err(self.contextualize_include_error(error, include_str));
291 }
292 }
293 }
294 (events, parser.anchor_offset())
295 }
296 };
297
298 self.push_replay_parser(
299 ReplayParser::new(events, next_anchor_offset),
300 include_str.into(),
301 );
302 Ok(())
303 }
304
305 fn contextualize_include_error(&self, error: ScanError, include_str: &str) -> ScanError {
306 let mut source_stack = self.stack();
307 source_stack.push(include_str.into());
308 error.with_source_stack(source_stack)
309 }
310
311 fn prepare_for_push(&mut self) {
312 if matches!(self.current.as_ref(), Some((Event::StreamEnd, _))) {
313 self.current = None;
314 }
315 }
316
317 pub fn push_str_parser(&mut self, mut parser: Parser<'input, StrInput<'input>>, name: String) {
322 self.prepare_for_push();
323 if let Some(parent) = self.parsers.last() {
324 parser.set_anchor_offset(parent.anchor_offset());
325 }
326 self.parsers.push(AnyParser::String { parser, name });
327 }
328
329 pub fn push_iter_parser(
334 &mut self,
335 mut parser: Parser<'static, BufferedInput<I>>,
336 name: String,
337 ) {
338 self.prepare_for_push();
339 if let Some(parent) = self.parsers.last() {
340 parser.set_anchor_offset(parent.anchor_offset());
341 }
342 self.parsers.push(AnyParser::Iter { parser, name });
343 }
344
345 pub fn push_custom_parser(&mut self, mut parser: Parser<'input, T>, name: String) {
350 self.prepare_for_push();
351 if let Some(parent) = self.parsers.last() {
352 parser.set_anchor_offset(parent.anchor_offset());
353 }
354 self.parsers.push(AnyParser::Custom { parser, name });
355 }
356
357 pub fn push_replay_parser(&mut self, mut parser: ReplayParser<'input>, name: String) {
362 self.prepare_for_push();
363 if let Some(parent) = self.parsers.last() {
364 let inherited = parent.anchor_offset();
365 parser.set_anchor_offset(parser.anchor_offset().max(inherited));
366 }
367
368 self.parsers.push(AnyParser::Replay { parser, name });
369 }
370
371 pub fn push_custom_parser_with_current(
376 &mut self,
377 mut parser: Parser<'input, T>,
378 name: String,
379 current: (Event<'input>, Span),
380 ) {
381 self.prepare_for_push();
382 if let Some(parent) = self.parsers.last() {
383 parser.set_anchor_offset(parent.anchor_offset());
384 }
385 self.parsers.push(AnyParser::Custom { parser, name });
386 self.current = if self.options.emit_comments || !matches!(current.0, Event::Comment(..)) {
387 Some(current)
388 } else {
389 None
390 };
391 }
392
393 #[must_use]
395 pub fn current_anchor_offset(&self) -> usize {
396 self.parsers.last().map_or(0, AnyParser::anchor_offset)
397 }
398
399 #[must_use]
401 pub fn stack(&self) -> Vec<String> {
402 self.parsers
403 .iter()
404 .map(|p| match p {
405 AnyParser::String { name, .. }
406 | AnyParser::Iter { name, .. }
407 | AnyParser::Custom { name, .. }
408 | AnyParser::Replay { name, .. } => name.clone(),
409 })
410 .collect()
411 }
412
413 fn contextualize_error(&self, error: ScanError) -> ScanError {
414 if self.parsers.len() > 1 {
415 error.with_source_stack(self.stack())
416 } else {
417 error
418 }
419 }
420
421 fn propagate_anchor_offset_from_popped(&mut self, popped: &AnyParser<'input, I, T>) {
422 if let Some(parent) = self.parsers.last_mut() {
423 let next_offset = parent.anchor_offset().max(popped.anchor_offset());
424 parent.set_anchor_offset(next_offset);
425 }
426 }
427
428 #[track_caller]
433 fn pop_parser_and_propagate_anchor_offset(&mut self) {
434 let popped = self.parsers.pop().unwrap();
435 self.propagate_anchor_offset_from_popped(&popped);
436 }
437
438 fn next_event_impl(&mut self) -> Result<(Event<'input>, Span), ScanError> {
439 loop {
440 let Some(any_parser) = self.parsers.last_mut() else {
441 return Ok((
442 Event::StreamEnd,
443 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
444 ));
445 };
446
447 let res = match any_parser {
448 AnyParser::String { parser, .. } => parser.next_event(),
449 AnyParser::Iter { parser, .. } => parser.next_event(),
450 AnyParser::Custom { parser, .. } => parser.next_event(),
451 AnyParser::Replay { parser, .. } => parser.next_event(),
452 };
453
454 match res {
455 Some(Ok((Event::StreamEnd, span))) => {
456 if self.parsers.len() == 1 {
457 self.parsers.pop();
458 return Ok((Event::StreamEnd, span));
459 }
460 self.pop_parser_and_propagate_anchor_offset();
461 }
462 None => {
463 if self.parsers.len() == 1 {
464 self.parsers.pop();
465 return Ok((
466 Event::StreamEnd,
467 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
468 ));
469 }
470 self.pop_parser_and_propagate_anchor_offset();
471 }
472 Some(Err(e)) => {
473 let e = self.contextualize_error(e);
474 self.pop_parser_and_propagate_anchor_offset();
475 return e.into_result();
476 }
477 Some(Ok((Event::DocumentEnd, span))) => {
478 if self.parsers.len() == 1 {
479 return Ok((Event::DocumentEnd, span));
480 }
481
482 let peek_res = loop {
484 let parser = self.parsers.last_mut().unwrap();
487 let peek = match parser {
488 AnyParser::String { parser, .. } => parser.peek(),
489 AnyParser::Iter { parser, .. } => parser.peek(),
490 AnyParser::Custom { parser, .. } => parser.peek(),
491 AnyParser::Replay { parser, .. } => parser.peek(),
492 };
493
494 if self.options.emit_comments
495 || !matches!(peek, Some(Ok((Event::Comment(..), _))))
496 {
497 break peek;
498 }
499
500 match parser {
501 AnyParser::String { parser, .. } => {
502 let _ = parser.next_event();
503 }
504 AnyParser::Iter { parser, .. } => {
505 let _ = parser.next_event();
506 }
507 AnyParser::Custom { parser, .. } => {
508 let _ = parser.next_event();
509 }
510 AnyParser::Replay { parser, .. } => {
511 let _ = parser.next_event();
512 }
513 }
514 };
515
516 match peek_res {
517 Some(Ok((Event::StreamEnd, _))) | None => {
518 self.pop_parser_and_propagate_anchor_offset();
519 }
520 Some(Ok(_)) => {
521 let error = self.contextualize_error(ScanError::from_kind(
522 span.start,
523 ErrorKind::MultipleDocumentsUnsupported,
524 ));
525 self.pop_parser_and_propagate_anchor_offset();
526 return Err(error);
527 }
528 Some(Err(e)) => {
529 let e = self.contextualize_error(e);
530 self.pop_parser_and_propagate_anchor_offset();
531 return Err(e);
532 }
533 }
534 }
535 Some(Ok(event)) => {
536 if !self.options.emit_comments && matches!(event.0, Event::Comment(..)) {
537 continue;
538 }
539 if self.parsers.len() > 1
540 && matches!(event.0, Event::StreamStart | Event::DocumentStart(..))
541 {
542 continue;
543 }
544 return Ok(event);
545 }
546 }
547 }
548 }
549}
550
551impl<'input, I, T> Default for ParserStack<'input, I, T>
552where
553 I: Iterator<Item = char>,
554 T: BorrowedInput<'input>,
555{
556 fn default() -> Self {
557 Self::new()
558 }
559}
560
561impl<'input, I, T> ParserTrait<'input> for ParserStack<'input, I, T>
562where
563 I: Iterator<Item = char>,
564 T: BorrowedInput<'input>,
565{
566 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
567 if let Some(ref x) = self.current {
568 Some(Ok(x))
569 } else if let Some(error) = &self.current_error {
570 Some(Err(error.clone()))
571 } else {
572 if self.stream_end_emitted {
573 return None;
574 }
575 match self.next_event_impl() {
576 Ok(token) => {
577 self.current = Some(token);
578 Some(Ok(self.current.as_ref().unwrap()))
579 }
580 Err(e) => {
581 self.current_error = Some(e.clone());
582 Some(Err(e))
583 }
584 }
585 }
586 }
587
588 fn next_event(&mut self) -> Option<ParseResult<'input>> {
589 if let Some(error) = self.current_error.take() {
590 self.stream_end_emitted = true;
591 return Some(Err(error));
592 }
593
594 if let Some(token) = self.current.take() {
595 if let Event::StreamEnd = token.0 {
596 self.stream_end_emitted = true;
597 }
598 return Some(Ok(token));
599 }
600 if self.stream_end_emitted {
601 return None;
602 }
603 match self.next_event_impl() {
604 Ok(token) => {
605 if let Event::StreamEnd = token.0 {
606 self.stream_end_emitted = true;
607 }
608 Some(Ok(token))
609 }
610 Err(e) => {
611 self.stream_end_emitted = true;
612 Some(Err(e))
613 }
614 }
615 }
616
617 fn load<R: SpannedEventReceiver<'input>>(
618 &mut self,
619 recv: &mut R,
620 multi: bool,
621 ) -> Result<(), ScanError> {
622 while let Some(res) = self.next_event() {
623 let (ev, span) = res?;
625
626 let is_doc_end = matches!(ev, Event::DocumentEnd);
628 let is_stream_end = matches!(ev, Event::StreamEnd);
629
630 recv.on_event(ev, span);
631
632 if is_stream_end {
633 break;
634 }
635
636 if !multi && is_doc_end {
638 break;
639 }
640 }
641
642 Ok(())
643 }
644}
645
646impl<'input, I, T> Iterator for ParserStack<'input, I, T>
647where
648 I: Iterator<Item = char>,
649 T: BorrowedInput<'input>,
650{
651 type Item = Result<(Event<'input>, Span), ScanError>;
652
653 fn next(&mut self) -> Option<Self::Item> {
654 self.next_event()
655 }
656}
657
658impl<'input, I, T> core::iter::FusedIterator for ParserStack<'input, I, T>
659where
660 I: Iterator<Item = char>,
661 T: BorrowedInput<'input>,
662{
663}