winnow/combinator/
impls.rs

1//! Opaque implementations of [`Parser`]
2
3use crate::combinator::trace;
4use crate::combinator::trace_result;
5use crate::combinator::DisplayDebug;
6#[cfg(feature = "unstable-recover")]
7#[cfg(feature = "std")]
8use crate::error::FromRecoverableError;
9use crate::error::{AddContext, FromExternalError, ParserError};
10use crate::lib::std::borrow::Borrow;
11use crate::lib::std::ops::Range;
12#[cfg(feature = "unstable-recover")]
13#[cfg(feature = "std")]
14use crate::stream::Recover;
15use crate::stream::StreamIsPartial;
16use crate::stream::{Location, Stream};
17use crate::*;
18
19/// [`Parser`] implementation for [`Parser::by_ref`]
20pub struct ByRef<'p, P, I, O, E> {
21    pub(crate) p: &'p mut P,
22    pub(crate) i: core::marker::PhantomData<I>,
23    pub(crate) o: core::marker::PhantomData<O>,
24    pub(crate) e: core::marker::PhantomData<E>,
25}
26
27impl<I, O, E, P> Parser<I, O, E> for ByRef<'_, P, I, O, E>
28where
29    P: Parser<I, O, E>,
30{
31    #[inline(always)]
32    fn parse_next(&mut self, i: &mut I) -> Result<O, E> {
33        self.p.parse_next(i)
34    }
35}
36
37/// [`Parser`] implementation for [`Parser::map`]
38pub struct Map<F, G, I, O, O2, E>
39where
40    F: Parser<I, O, E>,
41    G: FnMut(O) -> O2,
42{
43    pub(crate) parser: F,
44    pub(crate) map: G,
45    pub(crate) i: core::marker::PhantomData<I>,
46    pub(crate) o: core::marker::PhantomData<O>,
47    pub(crate) o2: core::marker::PhantomData<O2>,
48    pub(crate) e: core::marker::PhantomData<E>,
49}
50
51impl<F, G, I, O, O2, E> Parser<I, O2, E> for Map<F, G, I, O, O2, E>
52where
53    F: Parser<I, O, E>,
54    G: FnMut(O) -> O2,
55{
56    #[inline]
57    fn parse_next(&mut self, i: &mut I) -> Result<O2, E> {
58        match self.parser.parse_next(i) {
59            Err(e) => Err(e),
60            Ok(o) => Ok((self.map)(o)),
61        }
62    }
63}
64
65/// [`Parser`] implementation for [`Parser::try_map`]
66pub struct TryMap<F, G, I, O, O2, E, E2>
67where
68    F: Parser<I, O, E>,
69    G: FnMut(O) -> Result<O2, E2>,
70    I: Stream,
71    E: FromExternalError<I, E2>,
72    E: ParserError<I>,
73{
74    pub(crate) parser: F,
75    pub(crate) map: G,
76    pub(crate) i: core::marker::PhantomData<I>,
77    pub(crate) o: core::marker::PhantomData<O>,
78    pub(crate) o2: core::marker::PhantomData<O2>,
79    pub(crate) e: core::marker::PhantomData<E>,
80    pub(crate) e2: core::marker::PhantomData<E2>,
81}
82
83impl<F, G, I, O, O2, E, E2> Parser<I, O2, E> for TryMap<F, G, I, O, O2, E, E2>
84where
85    F: Parser<I, O, E>,
86    G: FnMut(O) -> Result<O2, E2>,
87    I: Stream,
88    E: FromExternalError<I, E2>,
89    E: ParserError<I>,
90{
91    #[inline]
92    fn parse_next(&mut self, input: &mut I) -> Result<O2, E> {
93        let start = input.checkpoint();
94        let o = self.parser.parse_next(input)?;
95        let res = (self.map)(o).map_err(|err| {
96            input.reset(&start);
97            E::from_external_error(input, err)
98        });
99        trace_result("verify", &res);
100        res
101    }
102}
103
104/// [`Parser`] implementation for [`Parser::verify_map`]
105pub struct VerifyMap<F, G, I, O, O2, E>
106where
107    F: Parser<I, O, E>,
108    G: FnMut(O) -> Option<O2>,
109    I: Stream,
110    E: ParserError<I>,
111{
112    pub(crate) parser: F,
113    pub(crate) map: G,
114    pub(crate) i: core::marker::PhantomData<I>,
115    pub(crate) o: core::marker::PhantomData<O>,
116    pub(crate) o2: core::marker::PhantomData<O2>,
117    pub(crate) e: core::marker::PhantomData<E>,
118}
119
120impl<F, G, I, O, O2, E> Parser<I, O2, E> for VerifyMap<F, G, I, O, O2, E>
121where
122    F: Parser<I, O, E>,
123    G: FnMut(O) -> Option<O2>,
124    I: Stream,
125    E: ParserError<I>,
126{
127    #[inline]
128    fn parse_next(&mut self, input: &mut I) -> Result<O2, E> {
129        let start = input.checkpoint();
130        let o = self.parser.parse_next(input)?;
131        let res = (self.map)(o).ok_or_else(|| {
132            input.reset(&start);
133            ParserError::from_input(input)
134        });
135        trace_result("verify", &res);
136        res
137    }
138}
139
140/// [`Parser`] implementation for [`Parser::and_then`]
141pub struct AndThen<F, G, I, O, O2, E>
142where
143    F: Parser<I, O, E>,
144    G: Parser<O, O2, E>,
145    O: StreamIsPartial,
146    I: Stream,
147{
148    pub(crate) outer: F,
149    pub(crate) inner: G,
150    pub(crate) i: core::marker::PhantomData<I>,
151    pub(crate) o: core::marker::PhantomData<O>,
152    pub(crate) o2: core::marker::PhantomData<O2>,
153    pub(crate) e: core::marker::PhantomData<E>,
154}
155
156impl<F, G, I, O, O2, E> Parser<I, O2, E> for AndThen<F, G, I, O, O2, E>
157where
158    F: Parser<I, O, E>,
159    G: Parser<O, O2, E>,
160    O: StreamIsPartial,
161    I: Stream,
162{
163    #[inline(always)]
164    fn parse_next(&mut self, i: &mut I) -> Result<O2, E> {
165        let start = i.checkpoint();
166        let mut o = self.outer.parse_next(i)?;
167        let _ = o.complete();
168        let o2 = self.inner.parse_next(&mut o).map_err(|err| {
169            i.reset(&start);
170            err
171        })?;
172        Ok(o2)
173    }
174}
175
176/// [`Parser`] implementation for [`Parser::parse_to`]
177pub struct ParseTo<P, I, O, O2, E>
178where
179    P: Parser<I, O, E>,
180    I: Stream,
181    O: crate::stream::ParseSlice<O2>,
182    E: ParserError<I>,
183{
184    pub(crate) p: P,
185    pub(crate) i: core::marker::PhantomData<I>,
186    pub(crate) o: core::marker::PhantomData<O>,
187    pub(crate) o2: core::marker::PhantomData<O2>,
188    pub(crate) e: core::marker::PhantomData<E>,
189}
190
191impl<P, I, O, O2, E> Parser<I, O2, E> for ParseTo<P, I, O, O2, E>
192where
193    P: Parser<I, O, E>,
194    I: Stream,
195    O: crate::stream::ParseSlice<O2>,
196    E: ParserError<I>,
197{
198    #[inline]
199    fn parse_next(&mut self, i: &mut I) -> Result<O2, E> {
200        let start = i.checkpoint();
201        let o = self.p.parse_next(i)?;
202        let res = o.parse_slice().ok_or_else(|| {
203            i.reset(&start);
204            ParserError::from_input(i)
205        });
206        trace_result("verify", &res);
207        res
208    }
209}
210
211/// [`Parser`] implementation for [`Parser::flat_map`]
212pub struct FlatMap<F, G, H, I, O, O2, E>
213where
214    F: Parser<I, O, E>,
215    G: FnMut(O) -> H,
216    H: Parser<I, O2, E>,
217{
218    pub(crate) f: F,
219    pub(crate) g: G,
220    pub(crate) h: core::marker::PhantomData<H>,
221    pub(crate) i: core::marker::PhantomData<I>,
222    pub(crate) o: core::marker::PhantomData<O>,
223    pub(crate) o2: core::marker::PhantomData<O2>,
224    pub(crate) e: core::marker::PhantomData<E>,
225}
226
227impl<F, G, H, I, O, O2, E> Parser<I, O2, E> for FlatMap<F, G, H, I, O, O2, E>
228where
229    F: Parser<I, O, E>,
230    G: FnMut(O) -> H,
231    H: Parser<I, O2, E>,
232{
233    #[inline(always)]
234    fn parse_next(&mut self, i: &mut I) -> Result<O2, E> {
235        let o = self.f.parse_next(i)?;
236        (self.g)(o).parse_next(i)
237    }
238}
239
240/// [`Parser`] implementation for [`Parser::complete_err`]
241pub struct CompleteErr<P, I, O, E> {
242    pub(crate) p: P,
243    pub(crate) i: core::marker::PhantomData<I>,
244    pub(crate) o: core::marker::PhantomData<O>,
245    pub(crate) e: core::marker::PhantomData<E>,
246}
247
248impl<P, I, O, E> Parser<I, O, E> for CompleteErr<P, I, O, E>
249where
250    P: Parser<I, O, E>,
251    I: Stream,
252    E: ParserError<I>,
253{
254    #[inline]
255    fn parse_next(&mut self, input: &mut I) -> Result<O, E> {
256        trace("complete_err", |input: &mut I| {
257            match (self.p).parse_next(input) {
258                Err(err) => match err.needed() {
259                    Some(_) => Err(ParserError::from_input(input)),
260                    None => Err(err),
261                },
262                rest => rest,
263            }
264        })
265        .parse_next(input)
266    }
267}
268
269/// [`Parser`] implementation for [`Parser::verify`]
270pub struct Verify<F, G, I, O, O2, E>
271where
272    F: Parser<I, O, E>,
273    G: FnMut(&O2) -> bool,
274    I: Stream,
275    O: Borrow<O2>,
276    O2: ?Sized,
277    E: ParserError<I>,
278{
279    pub(crate) parser: F,
280    pub(crate) filter: G,
281    pub(crate) i: core::marker::PhantomData<I>,
282    pub(crate) o: core::marker::PhantomData<O>,
283    pub(crate) o2: core::marker::PhantomData<O2>,
284    pub(crate) e: core::marker::PhantomData<E>,
285}
286
287impl<F, G, I, O, O2, E> Parser<I, O, E> for Verify<F, G, I, O, O2, E>
288where
289    F: Parser<I, O, E>,
290    G: FnMut(&O2) -> bool,
291    I: Stream,
292    O: Borrow<O2>,
293    O2: ?Sized,
294    E: ParserError<I>,
295{
296    #[inline]
297    fn parse_next(&mut self, input: &mut I) -> Result<O, E> {
298        let start = input.checkpoint();
299        let o = self.parser.parse_next(input)?;
300        let res = (self.filter)(o.borrow()).then_some(o).ok_or_else(|| {
301            input.reset(&start);
302            ParserError::from_input(input)
303        });
304        trace_result("verify", &res);
305        res
306    }
307}
308
309/// [`Parser`] implementation for [`Parser::value`]
310pub struct Value<F, I, O, O2, E>
311where
312    F: Parser<I, O, E>,
313    O2: Clone,
314{
315    pub(crate) parser: F,
316    pub(crate) val: O2,
317    pub(crate) i: core::marker::PhantomData<I>,
318    pub(crate) o: core::marker::PhantomData<O>,
319    pub(crate) e: core::marker::PhantomData<E>,
320}
321
322impl<F, I, O, O2, E> Parser<I, O2, E> for Value<F, I, O, O2, E>
323where
324    F: Parser<I, O, E>,
325    O2: Clone,
326{
327    #[inline]
328    fn parse_next(&mut self, input: &mut I) -> Result<O2, E> {
329        (self.parser).parse_next(input).map(|_| self.val.clone())
330    }
331}
332
333/// [`Parser`] implementation for [`Parser::default_value`]
334pub struct DefaultValue<F, I, O, O2, E>
335where
336    F: Parser<I, O, E>,
337    O2: core::default::Default,
338{
339    pub(crate) parser: F,
340    pub(crate) o2: core::marker::PhantomData<O2>,
341    pub(crate) i: core::marker::PhantomData<I>,
342    pub(crate) o: core::marker::PhantomData<O>,
343    pub(crate) e: core::marker::PhantomData<E>,
344}
345
346impl<F, I, O, O2, E> Parser<I, O2, E> for DefaultValue<F, I, O, O2, E>
347where
348    F: Parser<I, O, E>,
349    O2: core::default::Default,
350{
351    #[inline]
352    fn parse_next(&mut self, input: &mut I) -> Result<O2, E> {
353        (self.parser).parse_next(input).map(|_| O2::default())
354    }
355}
356
357/// [`Parser`] implementation for [`Parser::void`]
358pub struct Void<F, I, O, E>
359where
360    F: Parser<I, O, E>,
361{
362    pub(crate) parser: F,
363    pub(crate) i: core::marker::PhantomData<I>,
364    pub(crate) o: core::marker::PhantomData<O>,
365    pub(crate) e: core::marker::PhantomData<E>,
366}
367
368impl<F, I, O, E> Parser<I, (), E> for Void<F, I, O, E>
369where
370    F: Parser<I, O, E>,
371{
372    #[inline(always)]
373    fn parse_next(&mut self, input: &mut I) -> Result<(), E> {
374        (self.parser).parse_next(input).map(|_| ())
375    }
376}
377
378/// [`Parser`] implementation for [`Parser::take`]
379pub struct Take<F, I, O, E>
380where
381    F: Parser<I, O, E>,
382    I: Stream,
383{
384    pub(crate) parser: F,
385    pub(crate) i: core::marker::PhantomData<I>,
386    pub(crate) o: core::marker::PhantomData<O>,
387    pub(crate) e: core::marker::PhantomData<E>,
388}
389
390impl<I, O, E, F> Parser<I, <I as Stream>::Slice, E> for Take<F, I, O, E>
391where
392    F: Parser<I, O, E>,
393    I: Stream,
394{
395    #[inline]
396    fn parse_next(&mut self, input: &mut I) -> Result<<I as Stream>::Slice, E> {
397        let checkpoint = input.checkpoint();
398        match (self.parser).parse_next(input) {
399            Ok(_) => {
400                let offset = input.offset_from(&checkpoint);
401                input.reset(&checkpoint);
402                let taken = input.next_slice(offset);
403                Ok(taken)
404            }
405            Err(e) => Err(e),
406        }
407    }
408}
409
410/// [`Parser`] implementation for [`Parser::with_taken`]
411pub struct WithTaken<F, I, O, E>
412where
413    F: Parser<I, O, E>,
414    I: Stream,
415{
416    pub(crate) parser: F,
417    pub(crate) i: core::marker::PhantomData<I>,
418    pub(crate) o: core::marker::PhantomData<O>,
419    pub(crate) e: core::marker::PhantomData<E>,
420}
421
422impl<F, I, O, E> Parser<I, (O, <I as Stream>::Slice), E> for WithTaken<F, I, O, E>
423where
424    F: Parser<I, O, E>,
425    I: Stream,
426{
427    #[inline]
428    fn parse_next(&mut self, input: &mut I) -> Result<(O, <I as Stream>::Slice), E> {
429        let checkpoint = input.checkpoint();
430        match (self.parser).parse_next(input) {
431            Ok(result) => {
432                let offset = input.offset_from(&checkpoint);
433                input.reset(&checkpoint);
434                let taken = input.next_slice(offset);
435                Ok((result, taken))
436            }
437            Err(e) => Err(e),
438        }
439    }
440}
441
442/// [`Parser`] implementation for [`Parser::span`]
443pub struct Span<F, I, O, E>
444where
445    F: Parser<I, O, E>,
446    I: Stream + Location,
447{
448    pub(crate) parser: F,
449    pub(crate) i: core::marker::PhantomData<I>,
450    pub(crate) o: core::marker::PhantomData<O>,
451    pub(crate) e: core::marker::PhantomData<E>,
452}
453
454impl<I, O, E, F> Parser<I, Range<usize>, E> for Span<F, I, O, E>
455where
456    F: Parser<I, O, E>,
457    I: Stream + Location,
458{
459    #[inline]
460    fn parse_next(&mut self, input: &mut I) -> Result<Range<usize>, E> {
461        let start = input.current_token_start();
462        self.parser.parse_next(input).map(move |_| {
463            let end = input.previous_token_end();
464            start..end
465        })
466    }
467}
468
469/// [`Parser`] implementation for [`Parser::with_span`]
470pub struct WithSpan<F, I, O, E>
471where
472    F: Parser<I, O, E>,
473    I: Stream + Location,
474{
475    pub(crate) parser: F,
476    pub(crate) i: core::marker::PhantomData<I>,
477    pub(crate) o: core::marker::PhantomData<O>,
478    pub(crate) e: core::marker::PhantomData<E>,
479}
480
481impl<F, I, O, E> Parser<I, (O, Range<usize>), E> for WithSpan<F, I, O, E>
482where
483    F: Parser<I, O, E>,
484    I: Stream + Location,
485{
486    #[inline]
487    fn parse_next(&mut self, input: &mut I) -> Result<(O, Range<usize>), E> {
488        let start = input.current_token_start();
489        self.parser.parse_next(input).map(move |output| {
490            let end = input.previous_token_end();
491            (output, (start..end))
492        })
493    }
494}
495
496/// [`Parser`] implementation for [`Parser::output_into`]
497pub struct OutputInto<F, I, O, O2, E>
498where
499    F: Parser<I, O, E>,
500    O: Into<O2>,
501{
502    pub(crate) parser: F,
503    pub(crate) i: core::marker::PhantomData<I>,
504    pub(crate) o: core::marker::PhantomData<O>,
505    pub(crate) o2: core::marker::PhantomData<O2>,
506    pub(crate) e: core::marker::PhantomData<E>,
507}
508
509impl<F, I, O, O2, E> Parser<I, O2, E> for OutputInto<F, I, O, O2, E>
510where
511    F: Parser<I, O, E>,
512    O: Into<O2>,
513{
514    #[inline]
515    fn parse_next(&mut self, i: &mut I) -> Result<O2, E> {
516        self.parser.parse_next(i).map(|o| o.into())
517    }
518}
519
520/// [`Parser`] implementation for [`Parser::err_into`]
521pub struct ErrInto<F, I, O, E, E2>
522where
523    F: Parser<I, O, E>,
524    E: Into<E2>,
525{
526    pub(crate) parser: F,
527    pub(crate) i: core::marker::PhantomData<I>,
528    pub(crate) o: core::marker::PhantomData<O>,
529    pub(crate) e: core::marker::PhantomData<E>,
530    pub(crate) e2: core::marker::PhantomData<E2>,
531}
532
533impl<F, I, O, E, E2> Parser<I, O, E2> for ErrInto<F, I, O, E, E2>
534where
535    F: Parser<I, O, E>,
536    E: Into<E2>,
537{
538    #[inline]
539    fn parse_next(&mut self, i: &mut I) -> Result<O, E2> {
540        self.parser.parse_next(i).map_err(|err| err.into())
541    }
542}
543
544/// [`Parser`] implementation for [`Parser::context`]
545pub struct Context<F, I, O, E, C>
546where
547    F: Parser<I, O, E>,
548    I: Stream,
549    E: AddContext<I, C>,
550    E: ParserError<I>,
551    C: Clone + crate::lib::std::fmt::Debug,
552{
553    pub(crate) parser: F,
554    pub(crate) context: C,
555    pub(crate) i: core::marker::PhantomData<I>,
556    pub(crate) o: core::marker::PhantomData<O>,
557    pub(crate) e: core::marker::PhantomData<E>,
558}
559
560impl<F, I, O, E, C> Parser<I, O, E> for Context<F, I, O, E, C>
561where
562    F: Parser<I, O, E>,
563    I: Stream,
564    E: AddContext<I, C>,
565    E: ParserError<I>,
566    C: Clone + crate::lib::std::fmt::Debug,
567{
568    #[inline]
569    fn parse_next(&mut self, i: &mut I) -> Result<O, E> {
570        let context = self.context.clone();
571        trace(DisplayDebug(self.context.clone()), move |i: &mut I| {
572            let start = i.checkpoint();
573            (self.parser)
574                .parse_next(i)
575                .map_err(|err| err.add_context(i, &start, context.clone()))
576        })
577        .parse_next(i)
578    }
579}
580
581/// [`Parser`] implementation for [`Parser::context`]
582pub struct ContextWith<P, I, O, E, F, C, FI>
583where
584    P: Parser<I, O, E>,
585    I: Stream,
586    E: AddContext<I, C>,
587    E: ParserError<I>,
588    F: Fn() -> FI + Clone,
589    C: crate::lib::std::fmt::Debug,
590    FI: Iterator<Item = C>,
591{
592    pub(crate) parser: P,
593    pub(crate) context: F,
594    pub(crate) i: core::marker::PhantomData<I>,
595    pub(crate) o: core::marker::PhantomData<O>,
596    pub(crate) e: core::marker::PhantomData<E>,
597    pub(crate) c: core::marker::PhantomData<C>,
598    pub(crate) fi: core::marker::PhantomData<FI>,
599}
600
601impl<P, I, O, E, F, C, FI> Parser<I, O, E> for ContextWith<P, I, O, E, F, C, FI>
602where
603    P: Parser<I, O, E>,
604    I: Stream,
605    E: AddContext<I, C>,
606    E: ParserError<I>,
607    F: Fn() -> FI + Clone,
608    C: crate::lib::std::fmt::Debug,
609    FI: Iterator<Item = C>,
610{
611    #[inline]
612    fn parse_next(&mut self, i: &mut I) -> Result<O, E> {
613        let context = self.context.clone();
614        let start = i.checkpoint();
615        (self.parser).parse_next(i).map_err(|mut err| {
616            for context in context() {
617                err = err.add_context(i, &start, context);
618            }
619            err
620        })
621    }
622}
623
624/// [`Parser`] implementation for [`Parser::map_err`]
625pub struct MapErr<F, G, I, O, E, E2>
626where
627    F: Parser<I, O, E>,
628    G: FnMut(E) -> E2,
629{
630    pub(crate) parser: F,
631    pub(crate) map: G,
632    pub(crate) i: core::marker::PhantomData<I>,
633    pub(crate) o: core::marker::PhantomData<O>,
634    pub(crate) e: core::marker::PhantomData<E>,
635    pub(crate) e2: core::marker::PhantomData<E2>,
636}
637
638impl<F, G, I, O, E, E2> Parser<I, O, E2> for MapErr<F, G, I, O, E, E2>
639where
640    F: Parser<I, O, E>,
641    G: FnMut(E) -> E2,
642{
643    #[inline]
644    fn parse_next(&mut self, i: &mut I) -> Result<O, E2> {
645        match self.parser.parse_next(i) {
646            Err(e) => Err((self.map)(e)),
647            Ok(o) => Ok(o),
648        }
649    }
650}
651
652/// [`Parser`] implementation for [`Parser::retry_after`]
653#[cfg(feature = "unstable-recover")]
654#[cfg(feature = "std")]
655pub struct RetryAfter<P, R, I, O, E>
656where
657    P: Parser<I, O, E>,
658    R: Parser<I, (), E>,
659    I: Stream,
660    I: Recover<E>,
661    E: ParserError<I> + FromRecoverableError<I, E>,
662{
663    pub(crate) parser: P,
664    pub(crate) recover: R,
665    pub(crate) i: core::marker::PhantomData<I>,
666    pub(crate) o: core::marker::PhantomData<O>,
667    pub(crate) e: core::marker::PhantomData<E>,
668}
669
670#[cfg(feature = "unstable-recover")]
671#[cfg(feature = "std")]
672impl<P, R, I, O, E> Parser<I, O, E> for RetryAfter<P, R, I, O, E>
673where
674    P: Parser<I, O, E>,
675    R: Parser<I, (), E>,
676    I: Stream,
677    I: Recover<E>,
678    E: ParserError<I> + FromRecoverableError<I, E>,
679{
680    #[inline(always)]
681    fn parse_next(&mut self, i: &mut I) -> Result<O, E> {
682        if I::is_recovery_supported() {
683            retry_after_inner(&mut self.parser, &mut self.recover, i)
684        } else {
685            self.parser.parse_next(i)
686        }
687    }
688}
689
690#[cfg(feature = "unstable-recover")]
691#[cfg(feature = "std")]
692fn retry_after_inner<P, R, I, O, E>(parser: &mut P, recover: &mut R, i: &mut I) -> Result<O, E>
693where
694    P: Parser<I, O, E>,
695    R: Parser<I, (), E>,
696    I: Stream,
697    I: Recover<E>,
698    E: ParserError<I> + FromRecoverableError<I, E>,
699{
700    loop {
701        let token_start = i.checkpoint();
702        let mut err = match parser.parse_next(i) {
703            Ok(o) => {
704                return Ok(o);
705            }
706            Err(e) if e.is_incomplete() => return Err(e),
707            Err(err) => err,
708        };
709        let err_start = i.checkpoint();
710        let err_start_eof_offset = i.eof_offset();
711        if recover.parse_next(i).is_ok() {
712            let i_eof_offset = i.eof_offset();
713            if err_start_eof_offset == i_eof_offset {
714                // Didn't advance so bubble the error up
715            } else if let Err(err_) = i.record_err(&token_start, &err_start, err) {
716                err = err_;
717            } else {
718                continue;
719            }
720        }
721
722        i.reset(&err_start);
723        err = E::from_recoverable_error(&token_start, &err_start, i, err);
724        return Err(err);
725    }
726}
727
728/// [`Parser`] implementation for [`Parser::resume_after`]
729#[cfg(feature = "unstable-recover")]
730#[cfg(feature = "std")]
731pub struct ResumeAfter<P, R, I, O, E>
732where
733    P: Parser<I, O, E>,
734    R: Parser<I, (), E>,
735    I: Stream,
736    I: Recover<E>,
737    E: ParserError<I> + FromRecoverableError<I, E>,
738{
739    pub(crate) parser: P,
740    pub(crate) recover: R,
741    pub(crate) i: core::marker::PhantomData<I>,
742    pub(crate) o: core::marker::PhantomData<O>,
743    pub(crate) e: core::marker::PhantomData<E>,
744}
745
746#[cfg(feature = "unstable-recover")]
747#[cfg(feature = "std")]
748impl<P, R, I, O, E> Parser<I, Option<O>, E> for ResumeAfter<P, R, I, O, E>
749where
750    P: Parser<I, O, E>,
751    R: Parser<I, (), E>,
752    I: Stream,
753    I: Recover<E>,
754    E: ParserError<I> + FromRecoverableError<I, E>,
755{
756    #[inline(always)]
757    fn parse_next(&mut self, i: &mut I) -> Result<Option<O>, E> {
758        if I::is_recovery_supported() {
759            resume_after_inner(&mut self.parser, &mut self.recover, i)
760        } else {
761            self.parser.parse_next(i).map(Some)
762        }
763    }
764}
765
766#[cfg(feature = "unstable-recover")]
767#[cfg(feature = "std")]
768fn resume_after_inner<P, R, I, O, E>(
769    parser: &mut P,
770    recover: &mut R,
771    i: &mut I,
772) -> Result<Option<O>, E>
773where
774    P: Parser<I, O, E>,
775    R: Parser<I, (), E>,
776    I: Stream,
777    I: Recover<E>,
778    E: ParserError<I> + FromRecoverableError<I, E>,
779{
780    let token_start = i.checkpoint();
781    let mut err = match parser.parse_next(i) {
782        Ok(o) => {
783            return Ok(Some(o));
784        }
785        Err(e) if e.is_incomplete() => return Err(e),
786        Err(err) => err,
787    };
788    let err_start = i.checkpoint();
789    if recover.parse_next(i).is_ok() {
790        if let Err(err_) = i.record_err(&token_start, &err_start, err) {
791            err = err_;
792        } else {
793            return Ok(None);
794        }
795    }
796
797    i.reset(&err_start);
798    err = FromRecoverableError::from_recoverable_error(&token_start, &err_start, i, err);
799    Err(err)
800}