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 fn pop_parser_and_propagate_anchor_offset(&mut self) {
409 let popped = self.parsers.pop().unwrap();
410 self.propagate_anchor_offset_from_popped(&popped);
411 }
412
413 fn next_event_impl(&mut self) -> Result<(Event<'input>, Span), ScanError> {
414 loop {
415 let Some(any_parser) = self.parsers.last_mut() else {
416 return Ok((
417 Event::StreamEnd,
418 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
419 ));
420 };
421
422 let res = match any_parser {
423 AnyParser::String { parser, .. } => parser.next_event(),
424 AnyParser::Iter { parser, .. } => parser.next_event(),
425 AnyParser::Custom { parser, .. } => parser.next_event(),
426 AnyParser::Replay { parser, .. } => parser.next_event(),
427 };
428
429 match res {
430 Some(Ok((Event::StreamEnd, span))) => {
431 if self.parsers.len() == 1 {
432 self.parsers.pop();
433 return Ok((Event::StreamEnd, span));
434 }
435 self.pop_parser_and_propagate_anchor_offset();
436 }
437 None => {
438 if self.parsers.len() == 1 {
439 self.parsers.pop();
440 return Ok((
441 Event::StreamEnd,
442 Span::empty(crate::scanner::Marker::new(0, 1, 0)),
443 ));
444 }
445 self.pop_parser_and_propagate_anchor_offset();
446 }
447 Some(Err(e)) => {
448 let e = self.contextualize_error(e);
449 self.pop_parser_and_propagate_anchor_offset();
450 return e.into_result();
451 }
452 Some(Ok((Event::DocumentEnd, span))) => {
453 if self.parsers.len() == 1 {
454 return Ok((Event::DocumentEnd, span));
455 }
456
457 let peek_res = match self.parsers.last_mut().unwrap() {
459 AnyParser::String { parser, .. } => parser.peek(),
460 AnyParser::Iter { parser, .. } => parser.peek(),
461 AnyParser::Custom { parser, .. } => parser.peek(),
462 AnyParser::Replay { parser, .. } => parser.peek(),
463 };
464
465 match peek_res {
466 Some(Ok((Event::StreamEnd, _))) | None => {
467 self.pop_parser_and_propagate_anchor_offset();
468 }
469 Some(Ok(_)) => {
470 let error = self.contextualize_error(ScanError::from_kind(
471 span.start,
472 ErrorKind::MultipleDocumentsUnsupported,
473 ));
474 self.pop_parser_and_propagate_anchor_offset();
475 return Err(error);
476 }
477 Some(Err(e)) => {
478 let e = self.contextualize_error(e);
479 self.pop_parser_and_propagate_anchor_offset();
480 return Err(e);
481 }
482 }
483 }
484 Some(Ok(event)) => {
485 if self.parsers.len() > 1
486 && matches!(event.0, Event::StreamStart | Event::DocumentStart(..))
487 {
488 continue;
489 }
490 return Ok(event);
491 }
492 }
493 }
494 }
495}
496
497impl<'input, I, T> Default for ParserStack<'input, I, T>
498where
499 I: Iterator<Item = char>,
500 T: BorrowedInput<'input>,
501{
502 fn default() -> Self {
503 Self::new()
504 }
505}
506
507impl<'input, I, T> ParserTrait<'input> for ParserStack<'input, I, T>
508where
509 I: Iterator<Item = char>,
510 T: BorrowedInput<'input>,
511{
512 fn peek(&mut self) -> Option<Result<&(Event<'input>, Span), ScanError>> {
513 if let Some(ref x) = self.current {
514 Some(Ok(x))
515 } else if let Some(error) = &self.current_error {
516 Some(Err(error.clone()))
517 } else {
518 if self.stream_end_emitted {
519 return None;
520 }
521 match self.next_event_impl() {
522 Ok(token) => {
523 self.current = Some(token);
524 Some(Ok(self.current.as_ref().unwrap()))
525 }
526 Err(e) => {
527 self.current_error = Some(e.clone());
528 Some(Err(e))
529 }
530 }
531 }
532 }
533
534 fn next_event(&mut self) -> Option<ParseResult<'input>> {
535 if let Some(error) = self.current_error.take() {
536 self.stream_end_emitted = true;
537 return Some(Err(error));
538 }
539
540 if let Some(token) = self.current.take() {
541 if let Event::StreamEnd = token.0 {
542 self.stream_end_emitted = true;
543 }
544 return Some(Ok(token));
545 }
546 if self.stream_end_emitted {
547 return None;
548 }
549 match self.next_event_impl() {
550 Ok(token) => {
551 if let Event::StreamEnd = token.0 {
552 self.stream_end_emitted = true;
553 }
554 Some(Ok(token))
555 }
556 Err(e) => {
557 self.stream_end_emitted = true;
558 Some(Err(e))
559 }
560 }
561 }
562
563 fn load<R: SpannedEventReceiver<'input>>(
564 &mut self,
565 recv: &mut R,
566 multi: bool,
567 ) -> Result<(), ScanError> {
568 while let Some(res) = self.next_event() {
569 let (ev, span) = res?;
571
572 let is_doc_end = matches!(ev, Event::DocumentEnd);
574 let is_stream_end = matches!(ev, Event::StreamEnd);
575
576 recv.on_event(ev, span);
577
578 if is_stream_end {
579 break;
580 }
581
582 if !multi && is_doc_end {
584 break;
585 }
586 }
587
588 Ok(())
589 }
590}
591
592impl<'input, I, T> Iterator for ParserStack<'input, I, T>
593where
594 I: Iterator<Item = char>,
595 T: BorrowedInput<'input>,
596{
597 type Item = Result<(Event<'input>, Span), ScanError>;
598
599 fn next(&mut self) -> Option<Self::Item> {
600 self.next_event()
601 }
602}
603
604impl<'input, I, T> core::iter::FusedIterator for ParserStack<'input, I, T>
605where
606 I: Iterator<Item = char>,
607 T: BorrowedInput<'input>,
608{
609}