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 if let Some(anchor_id) = event.anchor_id() {
39 self.anchor_offset = self.anchor_offset.max(anchor_id.saturating_add(1));
40 }
41 }
42}
43
44impl<'input> ParserTrait<'input> for ReplayParser<'input> {
45 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
46 self.events.as_slice().first().map(Ok)
47 }
48
49 fn next_event(&mut self) -> Option<ParseResult<'input>> {
50 let event = self.events.next()?;
51 self.advance_anchor_offset(&event.0);
52 Some(Ok(event))
53 }
54
55 fn load<R: SpannedEventReceiver<'input>>(
56 &mut self,
57 recv: &mut R,
58 multi: bool,
59 ) -> Result<(), ScanError> {
60 while let Some(res) = self.next_event() {
61 let (ev, span) = res?;
62 let is_doc_end = matches!(ev, Event::DocumentEnd);
63 let is_stream_end = matches!(ev, Event::StreamEnd);
64 recv.on_event(ev, span);
65 if is_stream_end {
66 break;
67 }
68 if !multi && is_doc_end {
69 break;
70 }
71 }
72 Ok(())
73 }
74}
75
76impl<'input> Iterator for ReplayParser<'input> {
77 type Item = ParseResult<'input>;
78
79 fn next(&mut self) -> Option<Self::Item> {
80 self.next_event()
81 }
82}
83
84impl core::iter::FusedIterator for ReplayParser<'_> {}
85
86enum AnyParser<'input, I, T>
88where
89 I: Iterator<Item = char>,
90 T: BorrowedInput<'input>,
91{
92 String {
94 parser: Parser<'input, StrInput<'input>>,
96 name: String,
98 },
99 Iter {
101 parser: Parser<'static, BufferedInput<I>>,
103 name: String,
105 },
106 Custom {
108 parser: Parser<'input, T>,
110 name: String,
112 },
113 Replay {
115 parser: ReplayParser<'input>,
117 name: String,
119 },
120}
121
122impl<'input, I, T> AnyParser<'input, I, T>
123where
124 I: Iterator<Item = char>,
125 T: BorrowedInput<'input>,
126{
127 fn anchor_offset(&self) -> usize {
128 match self {
129 AnyParser::String { parser, .. } => parser.anchor_offset(),
130 AnyParser::Iter { parser, .. } => parser.anchor_offset(),
131 AnyParser::Custom { parser, .. } => parser.anchor_offset(),
132 AnyParser::Replay { parser, .. } => parser.anchor_offset(),
133 }
134 }
135
136 fn set_anchor_offset(&mut self, offset: usize) {
137 match self {
138 AnyParser::String { parser, .. } => parser.set_anchor_offset(offset),
139 AnyParser::Iter { parser, .. } => parser.set_anchor_offset(offset),
140 AnyParser::Custom { parser, .. } => parser.set_anchor_offset(offset),
141 AnyParser::Replay { parser, .. } => parser.set_anchor_offset(offset),
142 }
143 }
144}
145
146pub struct ParserStack<'input, I = core::iter::Empty<char>, T = StrInput<'input>>
171where
172 I: Iterator<Item = char>,
173 T: BorrowedInput<'input>,
174{
175 options: Options,
176 parsers: Vec<AnyParser<'input, I, T>>,
177 #[cfg(feature = "comments")]
179 pending_document_ends: Vec<(usize, Span)>,
180 current: Option<(Event<'input>, Span)>,
181 current_error: Option<ScanError>,
182 stream_end_emitted: bool,
183 #[allow(clippy::type_complexity)]
184 include_resolver: Option<Box<dyn FnMut(&str) -> Result<Cow<'input, str>, ScanError> + 'input>>,
185}
186
187impl<'input, I, T> ParserStack<'input, I, T>
188where
189 I: Iterator<Item = char>,
190 T: BorrowedInput<'input>,
191{
192 #[must_use]
194 pub fn new() -> Self {
195 Self::with_options(Options::default())
196 }
197
198 #[must_use]
209 pub fn with_options(options: Options) -> Self {
210 Self {
211 options,
212 parsers: Vec::new(),
213 #[cfg(feature = "comments")]
214 pending_document_ends: Vec::new(),
215 current: None,
216 current_error: None,
217 stream_end_emitted: false,
218 include_resolver: None,
219 }
220 }
221
222 pub fn set_resolver(
226 &mut self,
227 mut resolver: impl FnMut(&str) -> Result<String, ScanError> + 'input,
228 ) {
229 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Owned)));
230 }
231
232 pub fn set_borrowed_resolver(
239 &mut self,
240 mut resolver: impl FnMut(&str) -> Result<&'input str, ScanError> + 'input,
241 ) {
242 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Borrowed)));
243 }
244
245 pub fn push_include(&mut self, include_str: &str) -> Result<(), ScanError> {
256 let resolved = match &mut self.include_resolver {
257 Some(resolver) => resolver(include_str),
258 None => {
259 return Err(self.contextualize_include_error(
260 ScanError::from_kind(
261 crate::scanner::Marker::new(0, 1, 0),
262 ErrorKind::MissingIncludeResolver,
263 ),
264 include_str,
265 ));
266 }
267 };
268 let content = match resolved {
269 Ok(content) => content,
270 Err(error) => return Err(self.contextualize_include_error(error, include_str)),
271 };
272 let inherited_anchor_offset = self.parsers.last().map(AnyParser::anchor_offset);
273
274 let (events, next_anchor_offset) = match content {
275 Cow::Borrowed(content) => {
276 let mut parser = Parser::new_from_str_with_options(content, self.options.clone());
277 if let Some(anchor_offset) = inherited_anchor_offset {
278 parser.set_anchor_offset(anchor_offset);
279 }
280 let mut events = Vec::new();
281 while let Some(event) = parser.next_event() {
282 match event {
283 Ok(event) => events.push(event),
284 Err(error) => {
285 return Err(self.contextualize_include_error(error, include_str));
286 }
287 }
288 }
289 (events, parser.anchor_offset())
290 }
291 Cow::Owned(content) => {
292 let mut parser =
293 Parser::new_from_iter_with_options(content.chars(), self.options.clone());
294 if let Some(anchor_offset) = inherited_anchor_offset {
295 parser.set_anchor_offset(anchor_offset);
296 }
297 let mut events = Vec::new();
298 while let Some(event) = parser.next_event() {
299 match event {
300 Ok(event) => events.push(event),
301 Err(error) => {
302 return Err(self.contextualize_include_error(error, include_str));
303 }
304 }
305 }
306 (events, parser.anchor_offset())
307 }
308 };
309
310 self.push_replay_parser(
311 ReplayParser::new(events, next_anchor_offset),
312 include_str.into(),
313 );
314 Ok(())
315 }
316
317 fn contextualize_include_error(&self, error: ScanError, include_str: &str) -> ScanError {
318 let mut source_stack = self.stack();
319 source_stack.push(include_str.into());
320 error.with_source_stack(source_stack)
321 }
322
323 fn prepare_for_push(&mut self) {
324 if matches!(self.current.as_ref(), Some((Event::StreamEnd, _))) {
325 self.current = None;
326 }
327 }
328
329 pub fn push_str_parser(&mut self, mut parser: Parser<'input, StrInput<'input>>, name: String) {
334 self.prepare_for_push();
335 if let Some(parent) = self.parsers.last() {
336 parser.set_anchor_offset(parent.anchor_offset());
337 }
338 self.parsers.push(AnyParser::String { parser, name });
339 }
340
341 pub fn push_iter_parser(
346 &mut self,
347 mut parser: Parser<'static, BufferedInput<I>>,
348 name: String,
349 ) {
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::Iter { parser, name });
355 }
356
357 pub fn push_custom_parser(&mut self, mut parser: Parser<'input, T>, name: String) {
362 self.prepare_for_push();
363 if let Some(parent) = self.parsers.last() {
364 parser.set_anchor_offset(parent.anchor_offset());
365 }
366 self.parsers.push(AnyParser::Custom { parser, name });
367 }
368
369 pub fn push_replay_parser(&mut self, mut parser: ReplayParser<'input>, name: String) {
374 self.prepare_for_push();
375 if let Some(parent) = self.parsers.last() {
376 let inherited = parent.anchor_offset();
377 parser.set_anchor_offset(parser.anchor_offset().max(inherited));
378 }
379
380 self.parsers.push(AnyParser::Replay { parser, name });
381 }
382
383 pub fn push_custom_parser_with_current(
388 &mut self,
389 mut parser: Parser<'input, T>,
390 name: String,
391 current: (Event<'input>, Span),
392 ) {
393 self.prepare_for_push();
394 if let Some(parent) = self.parsers.last() {
395 parser.set_anchor_offset(parent.anchor_offset());
396 }
397 self.parsers.push(AnyParser::Custom { parser, name });
398 #[cfg(feature = "comments")]
399 {
400 self.current = if self.options.emit_comments || !matches!(current.0, Event::Comment(..))
401 {
402 Some(current)
403 } else {
404 None
405 };
406 }
407 #[cfg(not(feature = "comments"))]
408 {
409 self.current = Some(current);
410 }
411 }
412
413 #[must_use]
415 pub fn current_anchor_offset(&self) -> usize {
416 self.parsers.last().map_or(0, AnyParser::anchor_offset)
417 }
418
419 #[must_use]
421 pub fn stack(&self) -> Vec<String> {
422 self.parsers
423 .iter()
424 .map(|p| match p {
425 AnyParser::String { name, .. }
426 | AnyParser::Iter { name, .. }
427 | AnyParser::Custom { name, .. }
428 | AnyParser::Replay { name, .. } => name.clone(),
429 })
430 .collect()
431 }
432
433 fn contextualize_error(&self, error: ScanError) -> ScanError {
434 if self.parsers.len() > 1 {
435 error.with_source_stack(self.stack())
436 } else {
437 error
438 }
439 }
440
441 fn propagate_anchor_offset_from_popped(&mut self, popped: &AnyParser<'input, I, T>) {
442 if let Some(parent) = self.parsers.last_mut() {
443 let next_offset = parent.anchor_offset().max(popped.anchor_offset());
444 parent.set_anchor_offset(next_offset);
445 }
446 }
447
448 #[track_caller]
453 fn pop_parser_and_propagate_anchor_offset(&mut self) {
454 #[cfg(feature = "comments")]
455 if self
456 .pending_document_ends
457 .last()
458 .is_some_and(|(depth, _)| *depth == self.parsers.len())
459 {
460 self.pending_document_ends.pop();
461 }
462 let popped = self.parsers.pop().unwrap();
463 self.propagate_anchor_offset_from_popped(&popped);
464 }
465
466 fn next_event_impl(&mut self) -> Result<(Event<'input>, Span), ScanError> {
467 loop {
468 let Some(any_parser) = self.parsers.last_mut() else {
469 return Ok((
470 Event::StreamEnd,
471 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
472 ));
473 };
474
475 let res = match any_parser {
476 AnyParser::String { parser, .. } => parser.next_event(),
477 AnyParser::Iter { parser, .. } => parser.next_event(),
478 AnyParser::Custom { parser, .. } => parser.next_event(),
479 AnyParser::Replay { parser, .. } => parser.next_event(),
480 };
481
482 #[cfg(feature = "comments")]
483 if let Some(&(depth, span)) = self.pending_document_ends.last() {
484 if depth == self.parsers.len()
485 && matches!(&res, Some(Ok((event, _)))
486 if !matches!(event, Event::Comment(..) | Event::StreamEnd))
487 {
488 let error = self.contextualize_error(ScanError::from_kind(
489 span.start,
490 ErrorKind::MultipleDocumentsUnsupported,
491 ));
492 self.pop_parser_and_propagate_anchor_offset();
493 return Err(error);
494 }
495 }
496
497 match res {
498 Some(Ok((Event::StreamEnd, span))) => {
499 if self.parsers.len() == 1 {
500 self.parsers.pop();
501 return Ok((Event::StreamEnd, span));
502 }
503 self.pop_parser_and_propagate_anchor_offset();
504 }
505 None => {
506 if self.parsers.len() == 1 {
507 self.parsers.pop();
508 return Ok((
509 Event::StreamEnd,
510 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
511 ));
512 }
513 self.pop_parser_and_propagate_anchor_offset();
514 }
515 Some(Err(e)) => {
516 let e = self.contextualize_error(e);
517 self.pop_parser_and_propagate_anchor_offset();
518 return e.into_result();
519 }
520 Some(Ok((Event::DocumentEnd, span))) => {
521 if self.parsers.len() == 1 {
522 return Ok((Event::DocumentEnd, span));
523 }
524
525 #[cfg(feature = "comments")]
526 {
527 self.pending_document_ends.push((self.parsers.len(), span));
530 }
531 #[cfg(not(feature = "comments"))]
532 {
533 let next = match self.parsers.last_mut().unwrap() {
536 AnyParser::String { parser, .. } => parser.next_event(),
537 AnyParser::Iter { parser, .. } => parser.next_event(),
538 AnyParser::Custom { parser, .. } => parser.next_event(),
539 AnyParser::Replay { parser, .. } => parser.next_event(),
540 };
541 match next {
542 Some(Ok((Event::StreamEnd, _))) | None => {
543 self.pop_parser_and_propagate_anchor_offset();
544 }
545 Some(Err(error)) => {
546 let error = self.contextualize_error(error);
547 self.pop_parser_and_propagate_anchor_offset();
548 return Err(error);
549 }
550 Some(Ok(_)) => {
551 let error = self.contextualize_error(ScanError::from_kind(
552 span.start,
553 ErrorKind::MultipleDocumentsUnsupported,
554 ));
555 self.pop_parser_and_propagate_anchor_offset();
556 return Err(error);
557 }
558 }
559 }
560 }
561 Some(Ok(event)) => {
562 #[cfg(feature = "comments")]
563 if !self.options.emit_comments && matches!(event.0, Event::Comment(..)) {
564 continue;
565 }
566 if self.parsers.len() > 1
567 && matches!(event.0, Event::StreamStart | Event::DocumentStart(..))
568 {
569 continue;
570 }
571 return Ok(event);
572 }
573 }
574 }
575 }
576}
577
578impl<'input, I, T> Default for ParserStack<'input, I, T>
579where
580 I: Iterator<Item = char>,
581 T: BorrowedInput<'input>,
582{
583 fn default() -> Self {
584 Self::new()
585 }
586}
587
588impl<'input, I, T> ParserTrait<'input> for ParserStack<'input, I, T>
589where
590 I: Iterator<Item = char>,
591 T: BorrowedInput<'input>,
592{
593 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
594 if let Some(ref x) = self.current {
595 Some(Ok(x))
596 } else if let Some(error) = &self.current_error {
597 Some(Err(error.clone()))
598 } else {
599 if self.stream_end_emitted {
600 return None;
601 }
602 match self.next_event_impl() {
603 Ok(token) => {
604 self.current = Some(token);
605 Some(Ok(self.current.as_ref().unwrap()))
606 }
607 Err(e) => {
608 self.current_error = Some(e.clone());
609 Some(Err(e))
610 }
611 }
612 }
613 }
614
615 fn next_event(&mut self) -> Option<ParseResult<'input>> {
616 if let Some(error) = self.current_error.take() {
617 self.stream_end_emitted = true;
618 return Some(Err(error));
619 }
620
621 if let Some(token) = self.current.take() {
622 if let Event::StreamEnd = token.0 {
623 self.stream_end_emitted = true;
624 }
625 return Some(Ok(token));
626 }
627 if self.stream_end_emitted {
628 return None;
629 }
630 match self.next_event_impl() {
631 Ok(token) => {
632 if let Event::StreamEnd = token.0 {
633 self.stream_end_emitted = true;
634 }
635 Some(Ok(token))
636 }
637 Err(e) => {
638 self.stream_end_emitted = true;
639 Some(Err(e))
640 }
641 }
642 }
643
644 fn load<R: SpannedEventReceiver<'input>>(
645 &mut self,
646 recv: &mut R,
647 multi: bool,
648 ) -> Result<(), ScanError> {
649 while let Some(res) = self.next_event() {
650 let (ev, span) = res?;
652
653 let is_doc_end = matches!(ev, Event::DocumentEnd);
655 let is_stream_end = matches!(ev, Event::StreamEnd);
656
657 recv.on_event(ev, span);
658
659 if is_stream_end {
660 break;
661 }
662
663 if !multi && is_doc_end {
665 break;
666 }
667 }
668
669 Ok(())
670 }
671}
672
673impl<'input, I, T> Iterator for ParserStack<'input, I, T>
674where
675 I: Iterator<Item = char>,
676 T: BorrowedInput<'input>,
677{
678 type Item = Result<(Event<'input>, Span), ScanError>;
679
680 fn next(&mut self) -> Option<Self::Item> {
681 self.next_event()
682 }
683}
684
685impl<'input, I, T> core::iter::FusedIterator for ParserStack<'input, I, T>
686where
687 I: Iterator<Item = char>,
688 T: BorrowedInput<'input>,
689{
690}