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 pending_document_ends: Vec<(usize, Span)>,
177 current: Option<(Event<'input>, Span)>,
178 current_error: Option<ScanError>,
179 stream_end_emitted: bool,
180 #[allow(clippy::type_complexity)]
181 include_resolver: Option<Box<dyn FnMut(&str) -> Result<Cow<'input, str>, ScanError> + 'input>>,
182}
183
184impl<'input, I, T> ParserStack<'input, I, T>
185where
186 I: Iterator<Item = char>,
187 T: BorrowedInput<'input>,
188{
189 #[must_use]
191 pub fn new() -> Self {
192 Self::with_options(Options::default())
193 }
194
195 #[must_use]
203 pub fn with_options(options: Options) -> Self {
204 Self {
205 options,
206 parsers: Vec::new(),
207 pending_document_ends: Vec::new(),
208 current: None,
209 current_error: None,
210 stream_end_emitted: false,
211 include_resolver: None,
212 }
213 }
214
215 pub fn set_resolver(
219 &mut self,
220 mut resolver: impl FnMut(&str) -> Result<String, ScanError> + 'input,
221 ) {
222 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Owned)));
223 }
224
225 pub fn set_borrowed_resolver(
231 &mut self,
232 mut resolver: impl FnMut(&str) -> Result<&'input str, ScanError> + 'input,
233 ) {
234 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Borrowed)));
235 }
236
237 pub fn push_include(&mut self, include_str: &str) -> Result<(), ScanError> {
247 let resolved = match &mut self.include_resolver {
248 Some(resolver) => resolver(include_str),
249 None => {
250 return Err(self.contextualize_include_error(
251 ScanError::from_kind(
252 crate::scanner::Marker::new(0, 1, 0),
253 ErrorKind::MissingIncludeResolver,
254 ),
255 include_str,
256 ));
257 }
258 };
259 let content = match resolved {
260 Ok(content) => content,
261 Err(error) => return Err(self.contextualize_include_error(error, include_str)),
262 };
263 let inherited_anchor_offset = self.parsers.last().map(AnyParser::anchor_offset);
264
265 let (events, next_anchor_offset) = match content {
266 Cow::Borrowed(content) => {
267 let mut parser = Parser::new_from_str_with_options(content, self.options.clone());
268 if let Some(anchor_offset) = inherited_anchor_offset {
269 parser.set_anchor_offset(anchor_offset);
270 }
271 let mut events = Vec::new();
272 while let Some(event) = parser.next_event() {
273 match event {
274 Ok(event) => events.push(event),
275 Err(error) => {
276 return Err(self.contextualize_include_error(error, include_str));
277 }
278 }
279 }
280 (events, parser.anchor_offset())
281 }
282 Cow::Owned(content) => {
283 let mut parser =
284 Parser::new_from_iter_with_options(content.chars(), self.options.clone());
285 if let Some(anchor_offset) = inherited_anchor_offset {
286 parser.set_anchor_offset(anchor_offset);
287 }
288 let mut events = Vec::new();
289 while let Some(event) = parser.next_event() {
290 match event {
291 Ok(event) => events.push(event),
292 Err(error) => {
293 return Err(self.contextualize_include_error(error, include_str));
294 }
295 }
296 }
297 (events, parser.anchor_offset())
298 }
299 };
300
301 self.push_replay_parser(
302 ReplayParser::new(events, next_anchor_offset),
303 include_str.into(),
304 );
305 Ok(())
306 }
307
308 fn contextualize_include_error(&self, error: ScanError, include_str: &str) -> ScanError {
309 let mut source_stack = self.stack();
310 source_stack.push(include_str.into());
311 error.with_source_stack(source_stack)
312 }
313
314 fn prepare_for_push(&mut self) {
315 if matches!(self.current.as_ref(), Some((Event::StreamEnd, _))) {
316 self.current = None;
317 }
318 }
319
320 pub fn push_str_parser(&mut self, mut parser: Parser<'input, StrInput<'input>>, name: String) {
325 self.prepare_for_push();
326 if let Some(parent) = self.parsers.last() {
327 parser.set_anchor_offset(parent.anchor_offset());
328 }
329 self.parsers.push(AnyParser::String { parser, name });
330 }
331
332 pub fn push_iter_parser(
337 &mut self,
338 mut parser: Parser<'static, BufferedInput<I>>,
339 name: String,
340 ) {
341 self.prepare_for_push();
342 if let Some(parent) = self.parsers.last() {
343 parser.set_anchor_offset(parent.anchor_offset());
344 }
345 self.parsers.push(AnyParser::Iter { parser, name });
346 }
347
348 pub fn push_custom_parser(&mut self, mut parser: Parser<'input, T>, name: String) {
353 self.prepare_for_push();
354 if let Some(parent) = self.parsers.last() {
355 parser.set_anchor_offset(parent.anchor_offset());
356 }
357 self.parsers.push(AnyParser::Custom { parser, name });
358 }
359
360 pub fn push_replay_parser(&mut self, mut parser: ReplayParser<'input>, name: String) {
365 self.prepare_for_push();
366 if let Some(parent) = self.parsers.last() {
367 let inherited = parent.anchor_offset();
368 parser.set_anchor_offset(parser.anchor_offset().max(inherited));
369 }
370
371 self.parsers.push(AnyParser::Replay { parser, name });
372 }
373
374 pub fn push_custom_parser_with_current(
379 &mut self,
380 mut parser: Parser<'input, T>,
381 name: String,
382 current: (Event<'input>, Span),
383 ) {
384 self.prepare_for_push();
385 if let Some(parent) = self.parsers.last() {
386 parser.set_anchor_offset(parent.anchor_offset());
387 }
388 self.parsers.push(AnyParser::Custom { parser, name });
389 self.current = if self.options.emit_comments || !matches!(current.0, Event::Comment(..)) {
390 Some(current)
391 } else {
392 None
393 };
394 }
395
396 #[must_use]
398 pub fn current_anchor_offset(&self) -> usize {
399 self.parsers.last().map_or(0, AnyParser::anchor_offset)
400 }
401
402 #[must_use]
404 pub fn stack(&self) -> Vec<String> {
405 self.parsers
406 .iter()
407 .map(|p| match p {
408 AnyParser::String { name, .. }
409 | AnyParser::Iter { name, .. }
410 | AnyParser::Custom { name, .. }
411 | AnyParser::Replay { name, .. } => name.clone(),
412 })
413 .collect()
414 }
415
416 fn contextualize_error(&self, error: ScanError) -> ScanError {
417 if self.parsers.len() > 1 {
418 error.with_source_stack(self.stack())
419 } else {
420 error
421 }
422 }
423
424 fn propagate_anchor_offset_from_popped(&mut self, popped: &AnyParser<'input, I, T>) {
425 if let Some(parent) = self.parsers.last_mut() {
426 let next_offset = parent.anchor_offset().max(popped.anchor_offset());
427 parent.set_anchor_offset(next_offset);
428 }
429 }
430
431 #[track_caller]
436 fn pop_parser_and_propagate_anchor_offset(&mut self) {
437 if self
438 .pending_document_ends
439 .last()
440 .is_some_and(|(depth, _)| *depth == self.parsers.len())
441 {
442 self.pending_document_ends.pop();
443 }
444 let popped = self.parsers.pop().unwrap();
445 self.propagate_anchor_offset_from_popped(&popped);
446 }
447
448 fn next_event_impl(&mut self) -> Result<(Event<'input>, Span), ScanError> {
449 loop {
450 let Some(any_parser) = self.parsers.last_mut() else {
451 return Ok((
452 Event::StreamEnd,
453 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
454 ));
455 };
456
457 let res = match any_parser {
458 AnyParser::String { parser, .. } => parser.next_event(),
459 AnyParser::Iter { parser, .. } => parser.next_event(),
460 AnyParser::Custom { parser, .. } => parser.next_event(),
461 AnyParser::Replay { parser, .. } => parser.next_event(),
462 };
463
464 if let Some(&(depth, span)) = self.pending_document_ends.last() {
465 if depth == self.parsers.len()
466 && matches!(&res, Some(Ok((event, _)))
467 if !matches!(event, Event::Comment(..) | Event::StreamEnd))
468 {
469 let error = self.contextualize_error(ScanError::from_kind(
470 span.start,
471 ErrorKind::MultipleDocumentsUnsupported,
472 ));
473 self.pop_parser_and_propagate_anchor_offset();
474 return Err(error);
475 }
476 }
477
478 match res {
479 Some(Ok((Event::StreamEnd, span))) => {
480 if self.parsers.len() == 1 {
481 self.parsers.pop();
482 return Ok((Event::StreamEnd, span));
483 }
484 self.pop_parser_and_propagate_anchor_offset();
485 }
486 None => {
487 if self.parsers.len() == 1 {
488 self.parsers.pop();
489 return Ok((
490 Event::StreamEnd,
491 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
492 ));
493 }
494 self.pop_parser_and_propagate_anchor_offset();
495 }
496 Some(Err(e)) => {
497 let e = self.contextualize_error(e);
498 self.pop_parser_and_propagate_anchor_offset();
499 return e.into_result();
500 }
501 Some(Ok((Event::DocumentEnd, span))) => {
502 if self.parsers.len() == 1 {
503 return Ok((Event::DocumentEnd, span));
504 }
505
506 self.pending_document_ends.push((self.parsers.len(), span));
509 }
510 Some(Ok(event)) => {
511 if !self.options.emit_comments && matches!(event.0, Event::Comment(..)) {
512 continue;
513 }
514 if self.parsers.len() > 1
515 && matches!(event.0, Event::StreamStart | Event::DocumentStart(..))
516 {
517 continue;
518 }
519 return Ok(event);
520 }
521 }
522 }
523 }
524}
525
526impl<'input, I, T> Default for ParserStack<'input, I, T>
527where
528 I: Iterator<Item = char>,
529 T: BorrowedInput<'input>,
530{
531 fn default() -> Self {
532 Self::new()
533 }
534}
535
536impl<'input, I, T> ParserTrait<'input> for ParserStack<'input, I, T>
537where
538 I: Iterator<Item = char>,
539 T: BorrowedInput<'input>,
540{
541 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
542 if let Some(ref x) = self.current {
543 Some(Ok(x))
544 } else if let Some(error) = &self.current_error {
545 Some(Err(error.clone()))
546 } else {
547 if self.stream_end_emitted {
548 return None;
549 }
550 match self.next_event_impl() {
551 Ok(token) => {
552 self.current = Some(token);
553 Some(Ok(self.current.as_ref().unwrap()))
554 }
555 Err(e) => {
556 self.current_error = Some(e.clone());
557 Some(Err(e))
558 }
559 }
560 }
561 }
562
563 fn next_event(&mut self) -> Option<ParseResult<'input>> {
564 if let Some(error) = self.current_error.take() {
565 self.stream_end_emitted = true;
566 return Some(Err(error));
567 }
568
569 if let Some(token) = self.current.take() {
570 if let Event::StreamEnd = token.0 {
571 self.stream_end_emitted = true;
572 }
573 return Some(Ok(token));
574 }
575 if self.stream_end_emitted {
576 return None;
577 }
578 match self.next_event_impl() {
579 Ok(token) => {
580 if let Event::StreamEnd = token.0 {
581 self.stream_end_emitted = true;
582 }
583 Some(Ok(token))
584 }
585 Err(e) => {
586 self.stream_end_emitted = true;
587 Some(Err(e))
588 }
589 }
590 }
591
592 fn load<R: SpannedEventReceiver<'input>>(
593 &mut self,
594 recv: &mut R,
595 multi: bool,
596 ) -> Result<(), ScanError> {
597 while let Some(res) = self.next_event() {
598 let (ev, span) = res?;
600
601 let is_doc_end = matches!(ev, Event::DocumentEnd);
603 let is_stream_end = matches!(ev, Event::StreamEnd);
604
605 recv.on_event(ev, span);
606
607 if is_stream_end {
608 break;
609 }
610
611 if !multi && is_doc_end {
613 break;
614 }
615 }
616
617 Ok(())
618 }
619}
620
621impl<'input, I, T> Iterator for ParserStack<'input, I, T>
622where
623 I: Iterator<Item = char>,
624 T: BorrowedInput<'input>,
625{
626 type Item = Result<(Event<'input>, Span), ScanError>;
627
628 fn next(&mut self) -> Option<Self::Item> {
629 self.next_event()
630 }
631}
632
633impl<'input, I, T> core::iter::FusedIterator for ParserStack<'input, I, T>
634where
635 I: Iterator<Item = char>,
636 T: BorrowedInput<'input>,
637{
638}