1use crate::{
2 error::{ErrorKind, ScanError},
3 input::{str::StrInput, BorrowedInput, BufferedInput},
4 parser::{Event, ParseResult, Parser, ParserTrait, SpannedEventReceiver},
5 scanner::Span,
6};
7use alloc::{borrow::Cow, boxed::Box, string::String, vec::Vec};
8
9pub struct ReplayParser<'input> {
11 events: alloc::vec::IntoIter<(Event<'input>, Span)>,
12 anchor_offset: usize,
13}
14
15impl<'input> ReplayParser<'input> {
16 #[must_use]
18 pub fn new(events: Vec<(Event<'input>, Span)>, anchor_offset: usize) -> Self {
19 Self {
20 events: events.into_iter(),
21 anchor_offset,
22 }
23 }
24
25 #[must_use]
27 pub fn anchor_offset(&self) -> usize {
28 self.anchor_offset
29 }
30
31 pub fn set_anchor_offset(&mut self, offset: usize) {
33 self.anchor_offset = offset;
34 }
35
36 fn advance_anchor_offset(&mut self, event: &Event<'input>) {
37 let anchor_id = match event {
38 Event::Scalar(_, _, anchor_id, _)
39 | Event::SequenceStart(_, anchor_id, _)
40 | Event::MappingStart(_, anchor_id, _) => *anchor_id,
41 _ => 0,
42 };
43
44 if anchor_id > 0 {
45 self.anchor_offset = self.anchor_offset.max(anchor_id.saturating_add(1));
46 }
47 }
48}
49
50impl<'input> ParserTrait<'input> for ReplayParser<'input> {
51 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
52 self.events.as_slice().first().map(Ok)
53 }
54
55 fn next_event(&mut self) -> Option<ParseResult<'input>> {
56 let event = self.events.next()?;
57 self.advance_anchor_offset(&event.0);
58 Some(Ok(event))
59 }
60
61 fn load<R: SpannedEventReceiver<'input>>(
62 &mut self,
63 recv: &mut R,
64 multi: bool,
65 ) -> Result<(), ScanError> {
66 while let Some(res) = self.next_event() {
67 let (ev, span) = res?;
68 let is_doc_end = matches!(ev, Event::DocumentEnd);
69 let is_stream_end = matches!(ev, Event::StreamEnd);
70 recv.on_event(ev, span);
71 if is_stream_end {
72 break;
73 }
74 if !multi && is_doc_end {
75 break;
76 }
77 }
78 Ok(())
79 }
80}
81
82impl<'input> Iterator for ReplayParser<'input> {
83 type Item = ParseResult<'input>;
84
85 fn next(&mut self) -> Option<Self::Item> {
86 self.next_event()
87 }
88}
89
90impl core::iter::FusedIterator for ReplayParser<'_> {}
91
92enum AnyParser<'input, I, T>
94where
95 I: Iterator<Item = char>,
96 T: BorrowedInput<'input>,
97{
98 String {
100 parser: Parser<'input, StrInput<'input>>,
102 name: String,
104 },
105 Iter {
107 parser: Parser<'static, BufferedInput<I>>,
109 name: String,
111 },
112 Custom {
114 parser: Parser<'input, T>,
116 name: String,
118 },
119 Replay {
121 parser: ReplayParser<'input>,
123 name: String,
125 },
126}
127
128impl<'input, I, T> AnyParser<'input, I, T>
129where
130 I: Iterator<Item = char>,
131 T: BorrowedInput<'input>,
132{
133 fn anchor_offset(&self) -> usize {
134 match self {
135 AnyParser::String { parser, .. } => parser.anchor_offset(),
136 AnyParser::Iter { parser, .. } => parser.anchor_offset(),
137 AnyParser::Custom { parser, .. } => parser.anchor_offset(),
138 AnyParser::Replay { parser, .. } => parser.anchor_offset(),
139 }
140 }
141
142 fn set_anchor_offset(&mut self, offset: usize) {
143 match self {
144 AnyParser::String { parser, .. } => parser.set_anchor_offset(offset),
145 AnyParser::Iter { parser, .. } => parser.set_anchor_offset(offset),
146 AnyParser::Custom { parser, .. } => parser.set_anchor_offset(offset),
147 AnyParser::Replay { parser, .. } => parser.set_anchor_offset(offset),
148 }
149 }
150}
151
152pub struct ParserStack<'input, I = core::iter::Empty<char>, T = StrInput<'input>>
167where
168 I: Iterator<Item = char>,
169 T: BorrowedInput<'input>,
170{
171 parsers: Vec<AnyParser<'input, I, T>>,
172 current: Option<(Event<'input>, Span)>,
173 current_error: Option<ScanError>,
174 stream_end_emitted: bool,
175 #[allow(clippy::type_complexity)]
176 include_resolver: Option<Box<dyn FnMut(&str) -> Result<Cow<'input, str>, ScanError> + 'input>>,
177}
178
179impl<'input, I, T> ParserStack<'input, I, T>
180where
181 I: Iterator<Item = char>,
182 T: BorrowedInput<'input>,
183{
184 #[must_use]
186 pub fn new() -> Self {
187 Self {
188 parsers: Vec::new(),
189 current: None,
190 current_error: None,
191 stream_end_emitted: false,
192 include_resolver: None,
193 }
194 }
195
196 pub fn set_resolver(
200 &mut self,
201 mut resolver: impl FnMut(&str) -> Result<String, ScanError> + 'input,
202 ) {
203 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Owned)));
204 }
205
206 pub fn set_borrowed_resolver(
212 &mut self,
213 mut resolver: impl FnMut(&str) -> Result<&'input str, ScanError> + 'input,
214 ) {
215 self.include_resolver = Some(Box::new(move |name| resolver(name).map(Cow::Borrowed)));
216 }
217
218 pub fn push_include(&mut self, include_str: &str) -> Result<(), ScanError> {
228 let resolved = match &mut self.include_resolver {
229 Some(resolver) => resolver(include_str),
230 None => {
231 return Err(self.contextualize_include_error(
232 ScanError::from_kind(
233 crate::scanner::Marker::new(0, 1, 0),
234 ErrorKind::MissingIncludeResolver,
235 ),
236 include_str,
237 ));
238 }
239 };
240 let content = match resolved {
241 Ok(content) => content,
242 Err(error) => return Err(self.contextualize_include_error(error, include_str)),
243 };
244 let inherited_anchor_offset = self.parsers.last().map(AnyParser::anchor_offset);
245
246 let (events, next_anchor_offset) = match content {
247 Cow::Borrowed(content) => {
248 let mut parser = Parser::new_from_str(content);
249 if let Some(anchor_offset) = inherited_anchor_offset {
250 parser.set_anchor_offset(anchor_offset);
251 }
252 let mut events = Vec::new();
253 while let Some(event) = parser.next_event() {
254 match event {
255 Ok(event) => events.push(event),
256 Err(error) => {
257 return Err(self.contextualize_include_error(error, include_str));
258 }
259 }
260 }
261 (events, parser.anchor_offset())
262 }
263 Cow::Owned(content) => {
264 let mut parser =
265 Parser::new_from_iter(content.chars().collect::<Vec<_>>().into_iter());
266 if let Some(anchor_offset) = inherited_anchor_offset {
267 parser.set_anchor_offset(anchor_offset);
268 }
269 let mut events = Vec::new();
270 while let Some(event) = parser.next_event() {
271 match event {
272 Ok(event) => events.push(event),
273 Err(error) => {
274 return Err(self.contextualize_include_error(error, include_str));
275 }
276 }
277 }
278 (events, parser.anchor_offset())
279 }
280 };
281
282 self.push_replay_parser(
283 ReplayParser::new(events, next_anchor_offset),
284 include_str.into(),
285 );
286 Ok(())
287 }
288
289 fn contextualize_include_error(&self, error: ScanError, include_str: &str) -> ScanError {
290 let mut source_stack = self.stack();
291 source_stack.push(include_str.into());
292 error.with_source_stack(source_stack)
293 }
294
295 fn prepare_for_push(&mut self) {
296 if matches!(self.current.as_ref(), Some((Event::StreamEnd, _))) {
297 self.current = None;
298 }
299 }
300
301 pub fn push_str_parser(&mut self, mut parser: Parser<'input, StrInput<'input>>, name: String) {
306 self.prepare_for_push();
307 if let Some(parent) = self.parsers.last() {
308 parser.set_anchor_offset(parent.anchor_offset());
309 }
310 self.parsers.push(AnyParser::String { parser, name });
311 }
312
313 pub fn push_iter_parser(
318 &mut self,
319 mut parser: Parser<'static, BufferedInput<I>>,
320 name: String,
321 ) {
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::Iter { parser, name });
327 }
328
329 pub fn push_custom_parser(&mut self, mut parser: Parser<'input, T>, 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::Custom { parser, name });
339 }
340
341 pub fn push_replay_parser(&mut self, mut parser: ReplayParser<'input>, name: String) {
346 self.prepare_for_push();
347 if let Some(parent) = self.parsers.last() {
348 let inherited = parent.anchor_offset();
349 parser.set_anchor_offset(parser.anchor_offset().max(inherited));
350 }
351
352 self.parsers.push(AnyParser::Replay { parser, name });
353 }
354
355 pub fn push_custom_parser_with_current(
360 &mut self,
361 mut parser: Parser<'input, T>,
362 name: String,
363 current: (Event<'input>, Span),
364 ) {
365 self.prepare_for_push();
366 if let Some(parent) = self.parsers.last() {
367 parser.set_anchor_offset(parent.anchor_offset());
368 }
369 self.parsers.push(AnyParser::Custom { parser, name });
370 self.current = Some(current);
371 }
372
373 #[must_use]
375 pub fn current_anchor_offset(&self) -> usize {
376 self.parsers.last().map_or(0, AnyParser::anchor_offset)
377 }
378
379 #[must_use]
381 pub fn stack(&self) -> Vec<String> {
382 self.parsers
383 .iter()
384 .map(|p| match p {
385 AnyParser::String { name, .. }
386 | AnyParser::Iter { name, .. }
387 | AnyParser::Custom { name, .. }
388 | AnyParser::Replay { name, .. } => name.clone(),
389 })
390 .collect()
391 }
392
393 fn contextualize_error(&self, error: ScanError) -> ScanError {
394 if self.parsers.len() > 1 {
395 error.with_source_stack(self.stack())
396 } else {
397 error
398 }
399 }
400
401 fn propagate_anchor_offset_from_popped(&mut self, popped: &AnyParser<'input, I, T>) {
402 if let Some(parent) = self.parsers.last_mut() {
403 let next_offset = parent.anchor_offset().max(popped.anchor_offset());
404 parent.set_anchor_offset(next_offset);
405 }
406 }
407
408 #[track_caller]
413 fn pop_parser_and_propagate_anchor_offset(&mut self) {
414 let popped = self.parsers.pop().unwrap();
415 self.propagate_anchor_offset_from_popped(&popped);
416 }
417
418 fn next_event_impl(&mut self) -> Result<(Event<'input>, Span), ScanError> {
419 loop {
420 let Some(any_parser) = self.parsers.last_mut() else {
421 return Ok((
422 Event::StreamEnd,
423 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
424 ));
425 };
426
427 let res = match any_parser {
428 AnyParser::String { parser, .. } => parser.next_event(),
429 AnyParser::Iter { parser, .. } => parser.next_event(),
430 AnyParser::Custom { parser, .. } => parser.next_event(),
431 AnyParser::Replay { parser, .. } => parser.next_event(),
432 };
433
434 match res {
435 Some(Ok((Event::StreamEnd, span))) => {
436 if self.parsers.len() == 1 {
437 self.parsers.pop();
438 return Ok((Event::StreamEnd, span));
439 }
440 self.pop_parser_and_propagate_anchor_offset();
441 }
442 None => {
443 if self.parsers.len() == 1 {
444 self.parsers.pop();
445 return Ok((
446 Event::StreamEnd,
447 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
448 ));
449 }
450 self.pop_parser_and_propagate_anchor_offset();
451 }
452 Some(Err(e)) => {
453 let e = self.contextualize_error(e);
454 self.pop_parser_and_propagate_anchor_offset();
455 return e.into_result();
456 }
457 Some(Ok((Event::DocumentEnd, span))) => {
458 if self.parsers.len() == 1 {
459 return Ok((Event::DocumentEnd, span));
460 }
461
462 let peek_res = match self.parsers.last_mut().unwrap() {
464 AnyParser::String { parser, .. } => parser.peek(),
465 AnyParser::Iter { parser, .. } => parser.peek(),
466 AnyParser::Custom { parser, .. } => parser.peek(),
467 AnyParser::Replay { parser, .. } => parser.peek(),
468 };
469
470 match peek_res {
471 Some(Ok((Event::StreamEnd, _))) | None => {
472 self.pop_parser_and_propagate_anchor_offset();
473 }
474 Some(Ok(_)) => {
475 let error = self.contextualize_error(ScanError::from_kind(
476 span.start,
477 ErrorKind::MultipleDocumentsUnsupported,
478 ));
479 self.pop_parser_and_propagate_anchor_offset();
480 return Err(error);
481 }
482 Some(Err(e)) => {
483 let e = self.contextualize_error(e);
484 self.pop_parser_and_propagate_anchor_offset();
485 return Err(e);
486 }
487 }
488 }
489 Some(Ok(event)) => {
490 if self.parsers.len() > 1
491 && matches!(event.0, Event::StreamStart | Event::DocumentStart(..))
492 {
493 continue;
494 }
495 return Ok(event);
496 }
497 }
498 }
499 }
500}
501
502impl<'input, I, T> Default for ParserStack<'input, I, T>
503where
504 I: Iterator<Item = char>,
505 T: BorrowedInput<'input>,
506{
507 fn default() -> Self {
508 Self::new()
509 }
510}
511
512impl<'input, I, T> ParserTrait<'input> for ParserStack<'input, I, T>
513where
514 I: Iterator<Item = char>,
515 T: BorrowedInput<'input>,
516{
517 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
518 if let Some(ref x) = self.current {
519 Some(Ok(x))
520 } else if let Some(error) = &self.current_error {
521 Some(Err(error.clone()))
522 } else {
523 if self.stream_end_emitted {
524 return None;
525 }
526 match self.next_event_impl() {
527 Ok(token) => {
528 self.current = Some(token);
529 Some(Ok(self.current.as_ref().unwrap()))
530 }
531 Err(e) => {
532 self.current_error = Some(e.clone());
533 Some(Err(e))
534 }
535 }
536 }
537 }
538
539 fn next_event(&mut self) -> Option<ParseResult<'input>> {
540 if let Some(error) = self.current_error.take() {
541 self.stream_end_emitted = true;
542 return Some(Err(error));
543 }
544
545 if let Some(token) = self.current.take() {
546 if let Event::StreamEnd = token.0 {
547 self.stream_end_emitted = true;
548 }
549 return Some(Ok(token));
550 }
551 if self.stream_end_emitted {
552 return None;
553 }
554 match self.next_event_impl() {
555 Ok(token) => {
556 if let Event::StreamEnd = token.0 {
557 self.stream_end_emitted = true;
558 }
559 Some(Ok(token))
560 }
561 Err(e) => {
562 self.stream_end_emitted = true;
563 Some(Err(e))
564 }
565 }
566 }
567
568 fn load<R: SpannedEventReceiver<'input>>(
569 &mut self,
570 recv: &mut R,
571 multi: bool,
572 ) -> Result<(), ScanError> {
573 while let Some(res) = self.next_event() {
574 let (ev, span) = res?;
576
577 let is_doc_end = matches!(ev, Event::DocumentEnd);
579 let is_stream_end = matches!(ev, Event::StreamEnd);
580
581 recv.on_event(ev, span);
582
583 if is_stream_end {
584 break;
585 }
586
587 if !multi && is_doc_end {
589 break;
590 }
591 }
592
593 Ok(())
594 }
595}
596
597impl<'input, I, T> Iterator for ParserStack<'input, I, T>
598where
599 I: Iterator<Item = char>,
600 T: BorrowedInput<'input>,
601{
602 type Item = Result<(Event<'input>, Span), ScanError>;
603
604 fn next(&mut self) -> Option<Self::Item> {
605 self.next_event()
606 }
607}
608
609impl<'input, I, T> core::iter::FusedIterator for ParserStack<'input, I, T>
610where
611 I: Iterator<Item = char>,
612 T: BorrowedInput<'input>,
613{
614}