winnow/combinator/
multi.rs

1//! Combinators applying their child parser multiple times
2
3use crate::combinator::trace;
4use crate::error::FromExternalError;
5use crate::error::ParserError;
6use crate::stream::Accumulate;
7use crate::stream::Range;
8use crate::stream::Stream;
9use crate::Parser;
10use crate::Result;
11
12/// [`Accumulate`] the output of a parser into a container, like `Vec`
13///
14/// This stops before `n` when the parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
15/// [`cut_err`][crate::combinator::cut_err].
16///
17/// To take a series of tokens, [`Accumulate`] into a `()`
18/// (e.g. with [`.map(|()| ())`][Parser::map])
19/// and then [`Parser::take`].
20///
21/// <div class="warning">
22///
23/// **Warning:** If the parser passed to `repeat` accepts empty inputs
24/// (like `alpha0` or `digit0`), `repeat` will return an error,
25/// to prevent going into an infinite loop.
26///
27/// </div>
28///
29/// # Example
30///
31/// Zero or more repetitions:
32/// ```rust
33/// # #[cfg(feature = "std")] {
34/// # use winnow::{error::ErrMode, error::Needed};
35/// # use winnow::prelude::*;
36/// use winnow::combinator::repeat;
37///
38/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
39///   repeat(0.., "abc").parse_next(s)
40/// }
41///
42/// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
43/// assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
44/// assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
45/// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
46/// # }
47/// ```
48///
49/// One or more repetitions:
50/// ```rust
51/// # #[cfg(feature = "std")] {
52/// # use winnow::{error::ErrMode, error::Needed};
53/// # use winnow::prelude::*;
54/// use winnow::combinator::repeat;
55///
56/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
57///   repeat(1.., "abc").parse_next(s)
58/// }
59///
60/// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
61/// assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
62/// assert!(parser.parse_peek("123123").is_err());
63/// assert!(parser.parse_peek("").is_err());
64/// # }
65/// ```
66///
67/// Fixed number of repetitions:
68/// ```rust
69/// # #[cfg(feature = "std")] {
70/// # use winnow::{error::ErrMode, error::Needed};
71/// # use winnow::prelude::*;
72/// use winnow::combinator::repeat;
73///
74/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
75///   repeat(2, "abc").parse_next(s)
76/// }
77///
78/// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
79/// assert!(parser.parse_peek("abc123").is_err());
80/// assert!(parser.parse_peek("123123").is_err());
81/// assert!(parser.parse_peek("").is_err());
82/// assert_eq!(parser.parse_peek("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
83/// # }
84/// ```
85///
86/// Arbitrary repetitions:
87/// ```rust
88/// # #[cfg(feature = "std")] {
89/// # use winnow::{error::ErrMode, error::Needed};
90/// # use winnow::prelude::*;
91/// use winnow::combinator::repeat;
92///
93/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
94///   repeat(0..=2, "abc").parse_next(s)
95/// }
96///
97/// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
98/// assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
99/// assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
100/// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
101/// assert_eq!(parser.parse_peek("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
102/// # }
103/// ```
104#[doc(alias = "many0")]
105#[doc(alias = "count")]
106#[doc(alias = "many0_count")]
107#[doc(alias = "many1")]
108#[doc(alias = "many1_count")]
109#[doc(alias = "many_m_n")]
110#[doc(alias = "repeated")]
111#[doc(alias = "skip_many")]
112#[doc(alias = "skip_many1")]
113#[inline(always)]
114pub fn repeat<Input, Output, Accumulator, Error, ParseNext>(
115    occurrences: impl Into<Range>,
116    parser: ParseNext,
117) -> Repeat<ParseNext, Input, Output, Accumulator, Error>
118where
119    Input: Stream,
120    Accumulator: Accumulate<Output>,
121    ParseNext: Parser<Input, Output, Error>,
122    Error: ParserError<Input>,
123{
124    Repeat {
125        occurrences: occurrences.into(),
126        parser,
127        i: Default::default(),
128        o: Default::default(),
129        c: Default::default(),
130        e: Default::default(),
131    }
132}
133
134/// Customizable [`Parser`] implementation for [`repeat`]
135pub struct Repeat<P, I, O, C, E>
136where
137    P: Parser<I, O, E>,
138    I: Stream,
139    C: Accumulate<O>,
140    E: ParserError<I>,
141{
142    occurrences: Range,
143    parser: P,
144    i: core::marker::PhantomData<I>,
145    o: core::marker::PhantomData<O>,
146    c: core::marker::PhantomData<C>,
147    e: core::marker::PhantomData<E>,
148}
149
150impl<ParseNext, Input, Output, Error> Repeat<ParseNext, Input, Output, (), Error>
151where
152    ParseNext: Parser<Input, Output, Error>,
153    Input: Stream,
154    Error: ParserError<Input>,
155{
156    /// Repeats the embedded parser, calling `op` to gather the results
157    ///
158    /// This stops before `n` when the parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
159    /// [`cut_err`][crate::combinator::cut_err].
160    ///
161    /// # Arguments
162    /// * `init` A function returning the initial value.
163    /// * `op` The function that combines a result of `f` with
164    ///       the current accumulator.
165    ///
166    /// <div class="warning">
167    ///
168    /// **Warning:** If the parser passed to `fold` accepts empty inputs
169    /// (like `alpha0` or `digit0`), `fold_repeat` will return an error,
170    /// to prevent going into an infinite loop.
171    ///
172    /// </div>
173    ///
174    /// # Example
175    ///
176    /// Zero or more repetitions:
177    /// ```rust
178    /// # use winnow::{error::ErrMode, error::Needed};
179    /// # use winnow::prelude::*;
180    /// use winnow::combinator::repeat;
181    ///
182    /// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
183    ///   repeat(
184    ///     0..,
185    ///     "abc"
186    ///   ).fold(
187    ///     Vec::new,
188    ///     |mut acc: Vec<_>, item| {
189    ///       acc.push(item);
190    ///       acc
191    ///     }
192    ///   ).parse_next(s)
193    /// }
194    ///
195    /// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
196    /// assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
197    /// assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
198    /// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
199    /// ```
200    ///
201    /// One or more repetitions:
202    /// ```rust
203    /// # use winnow::{error::ErrMode, error::Needed};
204    /// # use winnow::prelude::*;
205    /// use winnow::combinator::repeat;
206    ///
207    /// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
208    ///   repeat(
209    ///     1..,
210    ///     "abc",
211    ///   ).fold(
212    ///     Vec::new,
213    ///     |mut acc: Vec<_>, item| {
214    ///       acc.push(item);
215    ///       acc
216    ///     }
217    ///   ).parse_next(s)
218    /// }
219    ///
220    /// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
221    /// assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
222    /// assert!(parser.parse_peek("123123").is_err());
223    /// assert!(parser.parse_peek("").is_err());
224    /// ```
225    ///
226    /// Arbitrary number of repetitions:
227    /// ```rust
228    /// # use winnow::{error::ErrMode, error::Needed};
229    /// # use winnow::prelude::*;
230    /// use winnow::combinator::repeat;
231    ///
232    /// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
233    ///   repeat(
234    ///     0..=2,
235    ///     "abc",
236    ///   ).fold(
237    ///     Vec::new,
238    ///     |mut acc: Vec<_>, item| {
239    ///       acc.push(item);
240    ///       acc
241    ///     }
242    ///   ).parse_next(s)
243    /// }
244    ///
245    /// assert_eq!(parser.parse_peek("abcabc"), Ok(("", vec!["abc", "abc"])));
246    /// assert_eq!(parser.parse_peek("abc123"), Ok(("123", vec!["abc"])));
247    /// assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
248    /// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
249    /// assert_eq!(parser.parse_peek("abcabcabc"), Ok(("abc", vec!["abc", "abc"])));
250    /// ```
251    #[doc(alias = "fold_many0")]
252    #[doc(alias = "fold_many1")]
253    #[doc(alias = "fold_many_m_n")]
254    #[doc(alias = "fold_repeat")]
255    #[inline(always)]
256    pub fn fold<Init, Op, Result>(
257        mut self,
258        mut init: Init,
259        mut op: Op,
260    ) -> impl Parser<Input, Result, Error>
261    where
262        Init: FnMut() -> Result,
263        Op: FnMut(Result, Output) -> Result,
264    {
265        let Range {
266            start_inclusive,
267            end_inclusive,
268        } = self.occurrences;
269        trace("repeat_fold", move |i: &mut Input| {
270            match (start_inclusive, end_inclusive) {
271                (0, None) => fold_repeat0_(&mut self.parser, &mut init, &mut op, i),
272                (1, None) => fold_repeat1_(&mut self.parser, &mut init, &mut op, i),
273                (start, end) => fold_repeat_m_n_(
274                    start,
275                    end.unwrap_or(usize::MAX),
276                    &mut self.parser,
277                    &mut init,
278                    &mut op,
279                    i,
280                ),
281            }
282        })
283    }
284
285    /// Akin to [`Repeat::fold`], but for containers that can reject an element.
286    ///
287    /// This stops before `n` when the parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
288    /// [`cut_err`][crate::combinator::cut_err]. Additionally, if the fold function returns `None`, the parser will
289    /// stop and return an error.
290    ///
291    /// # Arguments
292    /// * `init` A function returning the initial value.
293    /// * `op` The function that combines a result of `f` with
294    ///       the current accumulator.
295    ///
296    /// <div class="warning">
297    ///
298    /// **Warning:** If the parser passed to `repeat` accepts empty inputs
299    /// (like `alpha0` or `digit0`), `verify_fold` will return an error,
300    /// to prevent going into an infinite loop.
301    ///
302    /// </div>
303    ///
304    /// # Example
305    ///
306    /// Guaranteeing that the input had unique elements:
307    /// ```rust
308    /// # use winnow::{error::ErrMode, error::Needed};
309    /// # use winnow::prelude::*;
310    /// use winnow::combinator::repeat;
311    /// use std::collections::HashSet;
312    ///
313    /// fn parser<'i>(s: &mut &'i str) -> ModalResult<HashSet<&'i str>> {
314    ///   repeat(
315    ///     0..,
316    ///     "abc"
317    ///   ).verify_fold(
318    ///     HashSet::new,
319    ///     |mut acc: HashSet<_>, item| {
320    ///       if acc.insert(item) {
321    ///          Some(acc)
322    ///       } else {
323    ///          None
324    ///       }
325    ///     }
326    ///   ).parse_next(s)
327    /// }
328    ///
329    /// assert_eq!(parser.parse_peek("abc"), Ok(("", HashSet::from(["abc"]))));
330    /// assert!(parser.parse_peek("abcabc").is_err());
331    /// assert_eq!(parser.parse_peek("abc123"), Ok(("123", HashSet::from(["abc"]))));
332    /// assert_eq!(parser.parse_peek("123123"), Ok(("123123", HashSet::from([]))));
333    /// assert_eq!(parser.parse_peek(""), Ok(("", HashSet::from([]))));
334    /// ```
335    #[inline(always)]
336    pub fn verify_fold<Init, Op, Result>(
337        mut self,
338        mut init: Init,
339        mut op: Op,
340    ) -> impl Parser<Input, Result, Error>
341    where
342        Init: FnMut() -> Result,
343        Op: FnMut(Result, Output) -> Option<Result>,
344    {
345        let Range {
346            start_inclusive,
347            end_inclusive,
348        } = self.occurrences;
349        trace("repeat_verify_fold", move |input: &mut Input| {
350            verify_fold_m_n(
351                start_inclusive,
352                end_inclusive.unwrap_or(usize::MAX),
353                &mut self.parser,
354                &mut init,
355                &mut op,
356                input,
357            )
358        })
359    }
360
361    /// Akin to [`Repeat::fold`], but for containers that can error when an element is accumulated.
362    ///
363    /// This stops before `n` when the parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
364    /// [`cut_err`][crate::combinator::cut_err]. Additionally, if the fold function returns an error, the parser will
365    /// stop and return it.
366    ///
367    /// # Arguments
368    /// * `init` A function returning the initial value.
369    /// * `op` The function that combines a result of `f` with
370    ///       the current accumulator.
371    ///
372    /// <div class="warning">
373    ///
374    /// **Warning:** If the parser passed to `repeat` accepts empty inputs
375    /// (like `alpha0` or `digit0`), `try_fold` will return an error,
376    /// to prevent going into an infinite loop.
377    ///
378    /// </div>
379    ///
380    /// # Example
381    ///
382    /// Writing the output to a vector of bytes:
383    /// ```rust
384    /// # use winnow::{error::ErrMode, error::Needed};
385    /// # use winnow::prelude::*;
386    /// use winnow::combinator::repeat;
387    /// use std::io::Write;
388    /// use std::io::Error;
389    ///
390    /// fn parser(s: &mut &str) -> ModalResult<Vec<u8>> {
391    ///   repeat(
392    ///     0..,
393    ///     "abc"
394    ///   ).try_fold(
395    ///     Vec::new,
396    ///     |mut acc, item: &str| -> Result<_, Error> {
397    ///       acc.write(item.as_bytes())?;
398    ///       Ok(acc)
399    ///     }
400    ///   ).parse_next(s)
401    /// }
402    ///
403    /// assert_eq!(parser.parse_peek("abc"), Ok(("", b"abc".to_vec())));
404    /// assert_eq!(parser.parse_peek("abc123"), Ok(("123", b"abc".to_vec())));
405    /// assert_eq!(parser.parse_peek("123123"), Ok(("123123", vec![])));
406    /// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
407    #[inline(always)]
408    pub fn try_fold<Init, Op, OpError, Result>(
409        mut self,
410        mut init: Init,
411        mut op: Op,
412    ) -> impl Parser<Input, Result, Error>
413    where
414        Init: FnMut() -> Result,
415        Op: FnMut(Result, Output) -> core::result::Result<Result, OpError>,
416        Error: FromExternalError<Input, OpError>,
417    {
418        let Range {
419            start_inclusive,
420            end_inclusive,
421        } = self.occurrences;
422        trace("repeat_try_fold", move |input: &mut Input| {
423            try_fold_m_n(
424                start_inclusive,
425                end_inclusive.unwrap_or(usize::MAX),
426                &mut self.parser,
427                &mut init,
428                &mut op,
429                input,
430            )
431        })
432    }
433}
434
435impl<P, I, O, C, E> Parser<I, C, E> for Repeat<P, I, O, C, E>
436where
437    P: Parser<I, O, E>,
438    I: Stream,
439    C: Accumulate<O>,
440    E: ParserError<I>,
441{
442    #[inline(always)]
443    fn parse_next(&mut self, i: &mut I) -> Result<C, E> {
444        let Range {
445            start_inclusive,
446            end_inclusive,
447        } = self.occurrences;
448        trace("repeat", move |i: &mut I| {
449            match (start_inclusive, end_inclusive) {
450                (0, None) => repeat0_(&mut self.parser, i),
451                (1, None) => repeat1_(&mut self.parser, i),
452                (start, end) if Some(start) == end => repeat_n_(start, &mut self.parser, i),
453                (start, end) => repeat_m_n_(start, end.unwrap_or(usize::MAX), &mut self.parser, i),
454            }
455        })
456        .parse_next(i)
457    }
458}
459
460fn repeat0_<I, O, C, E, F>(f: &mut F, i: &mut I) -> Result<C, E>
461where
462    I: Stream,
463    C: Accumulate<O>,
464    F: Parser<I, O, E>,
465    E: ParserError<I>,
466{
467    let mut acc = C::initial(None);
468    loop {
469        let start = i.checkpoint();
470        let len = i.eof_offset();
471        match f.parse_next(i) {
472            Err(e) if e.is_backtrack() => {
473                i.reset(&start);
474                return Ok(acc);
475            }
476            Err(e) => return Err(e),
477            Ok(o) => {
478                // infinite loop check: the parser must always consume
479                if i.eof_offset() == len {
480                    return Err(ParserError::assert(
481                        i,
482                        "`repeat` parsers must always consume",
483                    ));
484                }
485
486                acc.accumulate(o);
487            }
488        }
489    }
490}
491
492fn repeat1_<I, O, C, E, F>(f: &mut F, i: &mut I) -> Result<C, E>
493where
494    I: Stream,
495    C: Accumulate<O>,
496    F: Parser<I, O, E>,
497    E: ParserError<I>,
498{
499    let start = i.checkpoint();
500    match f.parse_next(i) {
501        Err(e) => Err(e.append(i, &start)),
502        Ok(o) => {
503            let mut acc = C::initial(None);
504            acc.accumulate(o);
505
506            loop {
507                let start = i.checkpoint();
508                let len = i.eof_offset();
509                match f.parse_next(i) {
510                    Err(e) if e.is_backtrack() => {
511                        i.reset(&start);
512                        return Ok(acc);
513                    }
514                    Err(e) => return Err(e),
515                    Ok(o) => {
516                        // infinite loop check: the parser must always consume
517                        if i.eof_offset() == len {
518                            return Err(ParserError::assert(
519                                i,
520                                "`repeat` parsers must always consume",
521                            ));
522                        }
523
524                        acc.accumulate(o);
525                    }
526                }
527            }
528        }
529    }
530}
531
532fn repeat_n_<I, O, C, E, F>(count: usize, f: &mut F, i: &mut I) -> Result<C, E>
533where
534    I: Stream,
535    C: Accumulate<O>,
536    F: Parser<I, O, E>,
537    E: ParserError<I>,
538{
539    let mut res = C::initial(Some(count));
540
541    for _ in 0..count {
542        let start = i.checkpoint();
543        let len = i.eof_offset();
544        match f.parse_next(i) {
545            Ok(o) => {
546                // infinite loop check: the parser must always consume
547                if i.eof_offset() == len {
548                    return Err(ParserError::assert(
549                        i,
550                        "`repeat` parsers must always consume",
551                    ));
552                }
553
554                res.accumulate(o);
555            }
556            Err(e) => {
557                return Err(e.append(i, &start));
558            }
559        }
560    }
561
562    Ok(res)
563}
564
565fn repeat_m_n_<I, O, C, E, F>(min: usize, max: usize, parse: &mut F, input: &mut I) -> Result<C, E>
566where
567    I: Stream,
568    C: Accumulate<O>,
569    F: Parser<I, O, E>,
570    E: ParserError<I>,
571{
572    if min > max {
573        return Err(ParserError::assert(
574            input,
575            "range should be ascending, rather than descending",
576        ));
577    }
578
579    let mut res = C::initial(Some(min));
580    for count in 0..max {
581        let start = input.checkpoint();
582        let len = input.eof_offset();
583        match parse.parse_next(input) {
584            Ok(value) => {
585                // infinite loop check: the parser must always consume
586                if input.eof_offset() == len {
587                    return Err(ParserError::assert(
588                        input,
589                        "`repeat` parsers must always consume",
590                    ));
591                }
592
593                res.accumulate(value);
594            }
595            Err(e) if e.is_backtrack() => {
596                if count < min {
597                    return Err(e.append(input, &start));
598                } else {
599                    input.reset(&start);
600                    return Ok(res);
601                }
602            }
603            Err(e) => {
604                return Err(e);
605            }
606        }
607    }
608
609    Ok(res)
610}
611
612/// [`Accumulate`] the output of parser `f` into a container, like `Vec`, until the parser `g`
613/// produces a result.
614///
615/// Returns a tuple of the results of `f` in a `Vec` and the result of `g`.
616///
617/// `f` keeps going so long as `g` produces [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see [`cut_err`][crate::combinator::cut_err].
618///
619/// To take a series of tokens, [`Accumulate`] into a `()`
620/// (e.g. with [`.map(|((), _)| ())`][Parser::map])
621/// and then [`Parser::take`].
622///
623/// See also
624/// - [`take_till`][crate::token::take_till] for recognizing up-to a member of a [set of tokens][crate::stream::ContainsToken]
625/// - [`take_until`][crate::token::take_until] for recognizing up-to a [`literal`][crate::token::literal] (w/ optional simd optimizations)
626///
627/// # Example
628///
629/// ```rust
630/// # #[cfg(feature = "std")] {
631/// # use winnow::{error::ErrMode, error::Needed};
632/// # use winnow::prelude::*;
633/// use winnow::combinator::repeat_till;
634///
635/// fn parser<'i>(s: &mut &'i str) -> ModalResult<(Vec<&'i str>, &'i str)> {
636///   repeat_till(0.., "abc", "end").parse_next(s)
637/// };
638///
639/// assert_eq!(parser.parse_peek("abcabcend"), Ok(("", (vec!["abc", "abc"], "end"))));
640/// assert!(parser.parse_peek("abc123end").is_err());
641/// assert!(parser.parse_peek("123123end").is_err());
642/// assert!(parser.parse_peek("").is_err());
643/// assert_eq!(parser.parse_peek("abcendefg"), Ok(("efg", (vec!["abc"], "end"))));
644/// # }
645/// ```
646#[doc(alias = "many_till0")]
647pub fn repeat_till<Input, Output, Accumulator, Terminator, Error, ParseNext, TerminatorParser>(
648    occurrences: impl Into<Range>,
649    mut parse: ParseNext,
650    mut terminator: TerminatorParser,
651) -> impl Parser<Input, (Accumulator, Terminator), Error>
652where
653    Input: Stream,
654    Accumulator: Accumulate<Output>,
655    ParseNext: Parser<Input, Output, Error>,
656    TerminatorParser: Parser<Input, Terminator, Error>,
657    Error: ParserError<Input>,
658{
659    let Range {
660        start_inclusive,
661        end_inclusive,
662    } = occurrences.into();
663    trace("repeat_till", move |i: &mut Input| {
664        match (start_inclusive, end_inclusive) {
665            (0, None) => repeat_till0_(&mut parse, &mut terminator, i),
666            (start, end) => repeat_till_m_n_(
667                start,
668                end.unwrap_or(usize::MAX),
669                &mut parse,
670                &mut terminator,
671                i,
672            ),
673        }
674    })
675}
676
677fn repeat_till0_<I, O, C, P, E, F, G>(f: &mut F, g: &mut G, i: &mut I) -> Result<(C, P), E>
678where
679    I: Stream,
680    C: Accumulate<O>,
681    F: Parser<I, O, E>,
682    G: Parser<I, P, E>,
683    E: ParserError<I>,
684{
685    let mut res = C::initial(None);
686    loop {
687        let start = i.checkpoint();
688        let len = i.eof_offset();
689        match g.parse_next(i) {
690            Ok(o) => return Ok((res, o)),
691            Err(e) if e.is_backtrack() => {
692                i.reset(&start);
693                match f.parse_next(i) {
694                    Err(e) => return Err(e.append(i, &start)),
695                    Ok(o) => {
696                        // infinite loop check: the parser must always consume
697                        if i.eof_offset() == len {
698                            return Err(ParserError::assert(
699                                i,
700                                "`repeat` parsers must always consume",
701                            ));
702                        }
703
704                        res.accumulate(o);
705                    }
706                }
707            }
708            Err(e) => return Err(e),
709        }
710    }
711}
712
713fn repeat_till_m_n_<I, O, C, P, E, F, G>(
714    min: usize,
715    max: usize,
716    f: &mut F,
717    g: &mut G,
718    i: &mut I,
719) -> Result<(C, P), E>
720where
721    I: Stream,
722    C: Accumulate<O>,
723    F: Parser<I, O, E>,
724    G: Parser<I, P, E>,
725    E: ParserError<I>,
726{
727    if min > max {
728        return Err(ParserError::assert(
729            i,
730            "range should be ascending, rather than descending",
731        ));
732    }
733
734    let mut res = C::initial(Some(min));
735
736    let start = i.checkpoint();
737    for _ in 0..min {
738        match f.parse_next(i) {
739            Ok(o) => {
740                res.accumulate(o);
741            }
742            Err(e) => {
743                return Err(e.append(i, &start));
744            }
745        }
746    }
747    for count in min..=max {
748        let start = i.checkpoint();
749        let len = i.eof_offset();
750        match g.parse_next(i) {
751            Ok(o) => return Ok((res, o)),
752            Err(err) if err.is_backtrack() => {
753                if count == max {
754                    return Err(err);
755                }
756                i.reset(&start);
757                match f.parse_next(i) {
758                    Err(e) => {
759                        return Err(e.append(i, &start));
760                    }
761                    Ok(o) => {
762                        // infinite loop check: the parser must always consume
763                        if i.eof_offset() == len {
764                            return Err(ParserError::assert(
765                                i,
766                                "`repeat` parsers must always consume",
767                            ));
768                        }
769
770                        res.accumulate(o);
771                    }
772                }
773            }
774            Err(e) => return Err(e),
775        }
776    }
777    unreachable!()
778}
779
780/// [`Accumulate`] the output of a parser, interleaved with `sep`
781///
782/// This stops when either parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
783/// [`cut_err`][crate::combinator::cut_err].
784///
785/// To take a series of tokens, [`Accumulate`] into a `()`
786/// (e.g. with [`.map(|()| ())`][Parser::map])
787/// and then [`Parser::take`].
788///
789/// <div class="warning">
790///
791/// **Warning:** If the separator parser accepts empty inputs
792/// (like `alpha0` or `digit0`), `separated` will return an error,
793/// to prevent going into an infinite loop.
794///
795/// </div>
796///
797/// # Example
798///
799/// Zero or more repetitions:
800/// ```rust
801/// # #[cfg(feature = "std")] {
802/// # use winnow::{error::ErrMode, error::Needed};
803/// # use winnow::prelude::*;
804/// use winnow::combinator::separated;
805///
806/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
807///   separated(0.., "abc", "|").parse_next(s)
808/// }
809///
810/// assert_eq!(parser.parse_peek("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"])));
811/// assert_eq!(parser.parse_peek("abc123abc"), Ok(("123abc", vec!["abc"])));
812/// assert_eq!(parser.parse_peek("abc|def"), Ok(("|def", vec!["abc"])));
813/// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
814/// assert_eq!(parser.parse_peek("def|abc"), Ok(("def|abc", vec![])));
815/// # }
816/// ```
817///
818/// One or more repetitions:
819/// ```rust
820/// # #[cfg(feature = "std")] {
821/// # use winnow::{error::ErrMode, error::Needed};
822/// # use winnow::prelude::*;
823/// use winnow::combinator::separated;
824///
825/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
826///   separated(1.., "abc", "|").parse_next(s)
827/// }
828///
829/// assert_eq!(parser.parse_peek("abc|abc|abc"), Ok(("", vec!["abc", "abc", "abc"])));
830/// assert_eq!(parser.parse_peek("abc123abc"), Ok(("123abc", vec!["abc"])));
831/// assert_eq!(parser.parse_peek("abc|def"), Ok(("|def", vec!["abc"])));
832/// assert!(parser.parse_peek("").is_err());
833/// assert!(parser.parse_peek("def|abc").is_err());
834/// # }
835/// ```
836///
837/// Fixed number of repetitions:
838/// ```rust
839/// # #[cfg(feature = "std")] {
840/// # use winnow::{error::ErrMode, error::Needed};
841/// # use winnow::prelude::*;
842/// use winnow::combinator::separated;
843///
844/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
845///   separated(2, "abc", "|").parse_next(s)
846/// }
847///
848/// assert_eq!(parser.parse_peek("abc|abc|abc"), Ok(("|abc", vec!["abc", "abc"])));
849/// assert!(parser.parse_peek("abc123abc").is_err());
850/// assert!(parser.parse_peek("abc|def").is_err());
851/// assert!(parser.parse_peek("").is_err());
852/// assert!(parser.parse_peek("def|abc").is_err());
853/// # }
854/// ```
855///
856/// Arbitrary repetitions:
857/// ```rust
858/// # #[cfg(feature = "std")] {
859/// # use winnow::{error::ErrMode, error::Needed};
860/// # use winnow::prelude::*;
861/// use winnow::combinator::separated;
862///
863/// fn parser<'i>(s: &mut &'i str) -> ModalResult<Vec<&'i str>> {
864///   separated(0..=2, "abc", "|").parse_next(s)
865/// }
866///
867/// assert_eq!(parser.parse_peek("abc|abc|abc"), Ok(("|abc", vec!["abc", "abc"])));
868/// assert_eq!(parser.parse_peek("abc123abc"), Ok(("123abc", vec!["abc"])));
869/// assert_eq!(parser.parse_peek("abc|def"), Ok(("|def", vec!["abc"])));
870/// assert_eq!(parser.parse_peek(""), Ok(("", vec![])));
871/// assert_eq!(parser.parse_peek("def|abc"), Ok(("def|abc", vec![])));
872/// # }
873/// ```
874#[doc(alias = "sep_by")]
875#[doc(alias = "sep_by1")]
876#[doc(alias = "separated_list0")]
877#[doc(alias = "separated_list1")]
878#[doc(alias = "separated_m_n")]
879#[inline(always)]
880pub fn separated<Input, Output, Accumulator, Sep, Error, ParseNext, SepParser>(
881    occurrences: impl Into<Range>,
882    mut parser: ParseNext,
883    mut separator: SepParser,
884) -> impl Parser<Input, Accumulator, Error>
885where
886    Input: Stream,
887    Accumulator: Accumulate<Output>,
888    ParseNext: Parser<Input, Output, Error>,
889    SepParser: Parser<Input, Sep, Error>,
890    Error: ParserError<Input>,
891{
892    let Range {
893        start_inclusive,
894        end_inclusive,
895    } = occurrences.into();
896    trace("separated", move |input: &mut Input| {
897        match (start_inclusive, end_inclusive) {
898            (0, None) => separated0_(&mut parser, &mut separator, input),
899            (1, None) => separated1_(&mut parser, &mut separator, input),
900            (start, end) if Some(start) == end => {
901                separated_n_(start, &mut parser, &mut separator, input)
902            }
903            (start, end) => separated_m_n_(
904                start,
905                end.unwrap_or(usize::MAX),
906                &mut parser,
907                &mut separator,
908                input,
909            ),
910        }
911    })
912}
913
914fn separated0_<I, O, C, O2, E, P, S>(
915    parser: &mut P,
916    separator: &mut S,
917    input: &mut I,
918) -> Result<C, E>
919where
920    I: Stream,
921    C: Accumulate<O>,
922    P: Parser<I, O, E>,
923    S: Parser<I, O2, E>,
924    E: ParserError<I>,
925{
926    let mut acc = C::initial(None);
927
928    let start = input.checkpoint();
929    match parser.parse_next(input) {
930        Err(e) if e.is_backtrack() => {
931            input.reset(&start);
932            return Ok(acc);
933        }
934        Err(e) => return Err(e),
935        Ok(o) => {
936            acc.accumulate(o);
937        }
938    }
939
940    loop {
941        let start = input.checkpoint();
942        let len = input.eof_offset();
943        match separator.parse_next(input) {
944            Err(e) if e.is_backtrack() => {
945                input.reset(&start);
946                return Ok(acc);
947            }
948            Err(e) => return Err(e),
949            Ok(_) => {
950                // infinite loop check
951                if input.eof_offset() == len {
952                    return Err(ParserError::assert(
953                        input,
954                        "`separated` separator parser must always consume",
955                    ));
956                }
957
958                match parser.parse_next(input) {
959                    Err(e) if e.is_backtrack() => {
960                        input.reset(&start);
961                        return Ok(acc);
962                    }
963                    Err(e) => return Err(e),
964                    Ok(o) => {
965                        acc.accumulate(o);
966                    }
967                }
968            }
969        }
970    }
971}
972
973fn separated1_<I, O, C, O2, E, P, S>(
974    parser: &mut P,
975    separator: &mut S,
976    input: &mut I,
977) -> Result<C, E>
978where
979    I: Stream,
980    C: Accumulate<O>,
981    P: Parser<I, O, E>,
982    S: Parser<I, O2, E>,
983    E: ParserError<I>,
984{
985    let mut acc = C::initial(None);
986
987    // Parse the first element
988    match parser.parse_next(input) {
989        Err(e) => return Err(e),
990        Ok(o) => {
991            acc.accumulate(o);
992        }
993    }
994
995    loop {
996        let start = input.checkpoint();
997        let len = input.eof_offset();
998        match separator.parse_next(input) {
999            Err(e) if e.is_backtrack() => {
1000                input.reset(&start);
1001                return Ok(acc);
1002            }
1003            Err(e) => return Err(e),
1004            Ok(_) => {
1005                // infinite loop check
1006                if input.eof_offset() == len {
1007                    return Err(ParserError::assert(
1008                        input,
1009                        "`separated` separator parser must always consume",
1010                    ));
1011                }
1012
1013                match parser.parse_next(input) {
1014                    Err(e) if e.is_backtrack() => {
1015                        input.reset(&start);
1016                        return Ok(acc);
1017                    }
1018                    Err(e) => return Err(e),
1019                    Ok(o) => {
1020                        acc.accumulate(o);
1021                    }
1022                }
1023            }
1024        }
1025    }
1026}
1027
1028fn separated_n_<I, O, C, O2, E, P, S>(
1029    count: usize,
1030    parser: &mut P,
1031    separator: &mut S,
1032    input: &mut I,
1033) -> Result<C, E>
1034where
1035    I: Stream,
1036    C: Accumulate<O>,
1037    P: Parser<I, O, E>,
1038    S: Parser<I, O2, E>,
1039    E: ParserError<I>,
1040{
1041    let mut acc = C::initial(Some(count));
1042
1043    if count == 0 {
1044        return Ok(acc);
1045    }
1046
1047    let start = input.checkpoint();
1048    match parser.parse_next(input) {
1049        Err(e) => {
1050            return Err(e.append(input, &start));
1051        }
1052        Ok(o) => {
1053            acc.accumulate(o);
1054        }
1055    }
1056
1057    for _ in 1..count {
1058        let start = input.checkpoint();
1059        let len = input.eof_offset();
1060        match separator.parse_next(input) {
1061            Err(e) => {
1062                return Err(e.append(input, &start));
1063            }
1064            Ok(_) => {
1065                // infinite loop check
1066                if input.eof_offset() == len {
1067                    return Err(ParserError::assert(
1068                        input,
1069                        "`separated` separator parser must always consume",
1070                    ));
1071                }
1072
1073                match parser.parse_next(input) {
1074                    Err(e) => {
1075                        return Err(e.append(input, &start));
1076                    }
1077                    Ok(o) => {
1078                        acc.accumulate(o);
1079                    }
1080                }
1081            }
1082        }
1083    }
1084
1085    Ok(acc)
1086}
1087
1088fn separated_m_n_<I, O, C, O2, E, P, S>(
1089    min: usize,
1090    max: usize,
1091    parser: &mut P,
1092    separator: &mut S,
1093    input: &mut I,
1094) -> Result<C, E>
1095where
1096    I: Stream,
1097    C: Accumulate<O>,
1098    P: Parser<I, O, E>,
1099    S: Parser<I, O2, E>,
1100    E: ParserError<I>,
1101{
1102    if min > max {
1103        return Err(ParserError::assert(
1104            input,
1105            "range should be ascending, rather than descending",
1106        ));
1107    }
1108
1109    let mut acc = C::initial(Some(min));
1110
1111    let start = input.checkpoint();
1112    match parser.parse_next(input) {
1113        Err(e) if e.is_backtrack() => {
1114            if min == 0 {
1115                input.reset(&start);
1116                return Ok(acc);
1117            } else {
1118                return Err(e.append(input, &start));
1119            }
1120        }
1121        Err(e) => return Err(e),
1122        Ok(o) => {
1123            acc.accumulate(o);
1124        }
1125    }
1126
1127    for index in 1..max {
1128        let start = input.checkpoint();
1129        let len = input.eof_offset();
1130        match separator.parse_next(input) {
1131            Err(e) if e.is_backtrack() => {
1132                if index < min {
1133                    return Err(e.append(input, &start));
1134                } else {
1135                    input.reset(&start);
1136                    return Ok(acc);
1137                }
1138            }
1139            Err(e) => {
1140                return Err(e);
1141            }
1142            Ok(_) => {
1143                // infinite loop check
1144                if input.eof_offset() == len {
1145                    return Err(ParserError::assert(
1146                        input,
1147                        "`separated` separator parser must always consume",
1148                    ));
1149                }
1150
1151                match parser.parse_next(input) {
1152                    Err(e) if e.is_backtrack() => {
1153                        if index < min {
1154                            return Err(e.append(input, &start));
1155                        } else {
1156                            input.reset(&start);
1157                            return Ok(acc);
1158                        }
1159                    }
1160                    Err(e) => {
1161                        return Err(e);
1162                    }
1163                    Ok(o) => {
1164                        acc.accumulate(o);
1165                    }
1166                }
1167            }
1168        }
1169    }
1170
1171    Ok(acc)
1172}
1173
1174/// Alternates between two parsers, merging the results (left associative)
1175///
1176/// This stops when either parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
1177/// [`cut_err`][crate::combinator::cut_err].
1178///
1179/// # Example
1180///
1181/// ```rust
1182/// # use winnow::{error::ErrMode, error::Needed};
1183/// # use winnow::prelude::*;
1184/// use winnow::combinator::separated_foldl1;
1185/// use winnow::ascii::dec_int;
1186///
1187/// fn parser(s: &mut &str) -> ModalResult<i32> {
1188///   separated_foldl1(dec_int, "-", |l, _, r| l - r).parse_next(s)
1189/// }
1190///
1191/// assert_eq!(parser.parse_peek("9-3-5"), Ok(("", 1)));
1192/// assert!(parser.parse_peek("").is_err());
1193/// assert!(parser.parse_peek("def|abc").is_err());
1194/// ```
1195pub fn separated_foldl1<Input, Output, Sep, Error, ParseNext, SepParser, Op>(
1196    mut parser: ParseNext,
1197    mut sep: SepParser,
1198    mut op: Op,
1199) -> impl Parser<Input, Output, Error>
1200where
1201    Input: Stream,
1202    ParseNext: Parser<Input, Output, Error>,
1203    SepParser: Parser<Input, Sep, Error>,
1204    Error: ParserError<Input>,
1205    Op: FnMut(Output, Sep, Output) -> Output,
1206{
1207    trace("separated_foldl1", move |i: &mut Input| {
1208        let mut ol = parser.parse_next(i)?;
1209
1210        loop {
1211            let start = i.checkpoint();
1212            let len = i.eof_offset();
1213            match sep.parse_next(i) {
1214                Err(e) if e.is_backtrack() => {
1215                    i.reset(&start);
1216                    return Ok(ol);
1217                }
1218                Err(e) => return Err(e),
1219                Ok(s) => {
1220                    // infinite loop check: the parser must always consume
1221                    if i.eof_offset() == len {
1222                        return Err(ParserError::assert(
1223                            i,
1224                            "`repeat` parsers must always consume",
1225                        ));
1226                    }
1227
1228                    match parser.parse_next(i) {
1229                        Err(e) if e.is_backtrack() => {
1230                            i.reset(&start);
1231                            return Ok(ol);
1232                        }
1233                        Err(e) => return Err(e),
1234                        Ok(or) => {
1235                            ol = op(ol, s, or);
1236                        }
1237                    }
1238                }
1239            }
1240        }
1241    })
1242}
1243
1244/// Alternates between two parsers, merging the results (right associative)
1245///
1246/// This stops when either parser returns [`ErrMode::Backtrack`][crate::error::ErrMode::Backtrack]. To instead chain an error up, see
1247/// [`cut_err`][crate::combinator::cut_err].
1248///
1249/// # Example
1250///
1251/// ```rust
1252/// # use winnow::{error::ErrMode, error::Needed};
1253/// # use winnow::prelude::*;
1254/// use winnow::combinator::separated_foldr1;
1255/// use winnow::ascii::dec_uint;
1256///
1257/// fn parser(s: &mut &str) -> ModalResult<u32> {
1258///   separated_foldr1(dec_uint, "^", |l: u32, _, r: u32| l.pow(r)).parse_next(s)
1259/// }
1260///
1261/// assert_eq!(parser.parse_peek("2^3^2"), Ok(("", 512)));
1262/// assert_eq!(parser.parse_peek("2"), Ok(("", 2)));
1263/// assert!(parser.parse_peek("").is_err());
1264/// assert!(parser.parse_peek("def|abc").is_err());
1265/// ```
1266#[cfg(feature = "alloc")]
1267pub fn separated_foldr1<Input, Output, Sep, Error, ParseNext, SepParser, Op>(
1268    mut parser: ParseNext,
1269    mut sep: SepParser,
1270    mut op: Op,
1271) -> impl Parser<Input, Output, Error>
1272where
1273    Input: Stream,
1274    ParseNext: Parser<Input, Output, Error>,
1275    SepParser: Parser<Input, Sep, Error>,
1276    Error: ParserError<Input>,
1277    Op: FnMut(Output, Sep, Output) -> Output,
1278{
1279    trace("separated_foldr1", move |i: &mut Input| {
1280        let ol = parser.parse_next(i)?;
1281        let all: crate::lib::std::vec::Vec<(Sep, Output)> =
1282            repeat(0.., (sep.by_ref(), parser.by_ref())).parse_next(i)?;
1283        if let Some((s, or)) = all
1284            .into_iter()
1285            .rev()
1286            .reduce(|(sr, or), (sl, ol)| (sl, op(ol, sr, or)))
1287        {
1288            let merged = op(ol, s, or);
1289            Ok(merged)
1290        } else {
1291            Ok(ol)
1292        }
1293    })
1294}
1295
1296/// Repeats the embedded parser, filling the given slice with results.
1297///
1298/// This parser fails if the input runs out before the given slice is full.
1299///
1300/// # Example
1301///
1302/// ```rust
1303/// # use winnow::{error::ErrMode, error::Needed};
1304/// # use winnow::prelude::*;
1305/// use winnow::combinator::fill;
1306///
1307/// fn parser<'i>(s: &mut &'i str) -> ModalResult<[&'i str; 2]> {
1308///   let mut buf = ["", ""];
1309///   fill("abc", &mut buf).parse_next(s)?;
1310///   Ok(buf)
1311/// }
1312///
1313/// assert_eq!(parser.parse_peek("abcabc"), Ok(("", ["abc", "abc"])));
1314/// assert!(parser.parse_peek("abc123").is_err());
1315/// assert!(parser.parse_peek("123123").is_err());
1316/// assert!(parser.parse_peek("").is_err());
1317/// assert_eq!(parser.parse_peek("abcabcabc"), Ok(("abc", ["abc", "abc"])));
1318/// ```
1319pub fn fill<'i, Input, Output, Error, ParseNext>(
1320    mut parser: ParseNext,
1321    buf: &'i mut [Output],
1322) -> impl Parser<Input, (), Error> + 'i
1323where
1324    Input: Stream + 'i,
1325    ParseNext: Parser<Input, Output, Error> + 'i,
1326    Error: ParserError<Input> + 'i,
1327{
1328    trace("fill", move |i: &mut Input| {
1329        for elem in buf.iter_mut() {
1330            let start = i.checkpoint();
1331            match parser.parse_next(i) {
1332                Ok(o) => {
1333                    *elem = o;
1334                }
1335                Err(e) => {
1336                    return Err(e.append(i, &start));
1337                }
1338            }
1339        }
1340
1341        Ok(())
1342    })
1343}
1344
1345fn fold_repeat0_<I, O, E, F, G, H, R>(
1346    f: &mut F,
1347    init: &mut H,
1348    g: &mut G,
1349    input: &mut I,
1350) -> Result<R, E>
1351where
1352    I: Stream,
1353    F: Parser<I, O, E>,
1354    G: FnMut(R, O) -> R,
1355    H: FnMut() -> R,
1356    E: ParserError<I>,
1357{
1358    let mut res = init();
1359
1360    loop {
1361        let start = input.checkpoint();
1362        let len = input.eof_offset();
1363        match f.parse_next(input) {
1364            Ok(o) => {
1365                // infinite loop check: the parser must always consume
1366                if input.eof_offset() == len {
1367                    return Err(ParserError::assert(
1368                        input,
1369                        "`repeat` parsers must always consume",
1370                    ));
1371                }
1372
1373                res = g(res, o);
1374            }
1375            Err(e) if e.is_backtrack() => {
1376                input.reset(&start);
1377                return Ok(res);
1378            }
1379            Err(e) => {
1380                return Err(e);
1381            }
1382        }
1383    }
1384}
1385
1386fn fold_repeat1_<I, O, E, F, G, H, R>(
1387    f: &mut F,
1388    init: &mut H,
1389    g: &mut G,
1390    input: &mut I,
1391) -> Result<R, E>
1392where
1393    I: Stream,
1394    F: Parser<I, O, E>,
1395    G: FnMut(R, O) -> R,
1396    H: FnMut() -> R,
1397    E: ParserError<I>,
1398{
1399    let init = init();
1400    let start = input.checkpoint();
1401    match f.parse_next(input) {
1402        Err(e) => Err(e.append(input, &start)),
1403        Ok(o1) => {
1404            let mut acc = g(init, o1);
1405
1406            loop {
1407                let start = input.checkpoint();
1408                let len = input.eof_offset();
1409                match f.parse_next(input) {
1410                    Err(e) if e.is_backtrack() => {
1411                        input.reset(&start);
1412                        break;
1413                    }
1414                    Err(e) => return Err(e),
1415                    Ok(o) => {
1416                        // infinite loop check: the parser must always consume
1417                        if input.eof_offset() == len {
1418                            return Err(ParserError::assert(
1419                                input,
1420                                "`repeat` parsers must always consume",
1421                            ));
1422                        }
1423
1424                        acc = g(acc, o);
1425                    }
1426                }
1427            }
1428
1429            Ok(acc)
1430        }
1431    }
1432}
1433
1434fn fold_repeat_m_n_<I, O, E, F, G, H, R>(
1435    min: usize,
1436    max: usize,
1437    parse: &mut F,
1438    init: &mut H,
1439    fold: &mut G,
1440    input: &mut I,
1441) -> Result<R, E>
1442where
1443    I: Stream,
1444    F: Parser<I, O, E>,
1445    G: FnMut(R, O) -> R,
1446    H: FnMut() -> R,
1447    E: ParserError<I>,
1448{
1449    if min > max {
1450        return Err(ParserError::assert(
1451            input,
1452            "range should be ascending, rather than descending",
1453        ));
1454    }
1455
1456    let mut acc = init();
1457    for count in 0..max {
1458        let start = input.checkpoint();
1459        let len = input.eof_offset();
1460        match parse.parse_next(input) {
1461            Ok(value) => {
1462                // infinite loop check: the parser must always consume
1463                if input.eof_offset() == len {
1464                    return Err(ParserError::assert(
1465                        input,
1466                        "`repeat` parsers must always consume",
1467                    ));
1468                }
1469
1470                acc = fold(acc, value);
1471            }
1472            //FInputXMError: handle failure properly
1473            Err(err) if err.is_backtrack() => {
1474                if count < min {
1475                    return Err(err.append(input, &start));
1476                } else {
1477                    input.reset(&start);
1478                    break;
1479                }
1480            }
1481            Err(e) => return Err(e),
1482        }
1483    }
1484
1485    Ok(acc)
1486}
1487
1488#[inline(always)]
1489fn verify_fold_m_n<I, O, E, F, G, H, R>(
1490    min: usize,
1491    max: usize,
1492    parse: &mut F,
1493    init: &mut H,
1494    fold: &mut G,
1495    input: &mut I,
1496) -> Result<R, E>
1497where
1498    I: Stream,
1499    F: Parser<I, O, E>,
1500    G: FnMut(R, O) -> Option<R>,
1501    H: FnMut() -> R,
1502    E: ParserError<I>,
1503{
1504    if min > max {
1505        return Err(ParserError::assert(
1506            input,
1507            "range should be ascending, rather than descending",
1508        ));
1509    }
1510
1511    let mut acc = init();
1512    for count in 0..max {
1513        let start = input.checkpoint();
1514        let len = input.eof_offset();
1515        match parse.parse_next(input) {
1516            Ok(value) => {
1517                // infinite loop check: the parser must always consume
1518                if input.eof_offset() == len {
1519                    return Err(ParserError::assert(
1520                        input,
1521                        "`repeat` parsers must always consume",
1522                    ));
1523                }
1524
1525                let Some(tmp) = fold(acc, value) else {
1526                    input.reset(&start);
1527                    let res = Err(ParserError::from_input(input));
1528                    super::debug::trace_result("verify_fold", &res);
1529                    return res;
1530                };
1531                acc = tmp;
1532            }
1533            //FInputXMError: handle failure properly
1534            Err(err) if err.is_backtrack() => {
1535                if count < min {
1536                    return Err(err.append(input, &start));
1537                } else {
1538                    input.reset(&start);
1539                    break;
1540                }
1541            }
1542            Err(e) => return Err(e),
1543        }
1544    }
1545
1546    Ok(acc)
1547}
1548
1549#[inline(always)]
1550fn try_fold_m_n<I, O, E, F, G, H, R, GE>(
1551    min: usize,
1552    max: usize,
1553    parse: &mut F,
1554    init: &mut H,
1555    fold: &mut G,
1556    input: &mut I,
1557) -> Result<R, E>
1558where
1559    I: Stream,
1560    F: Parser<I, O, E>,
1561    G: FnMut(R, O) -> Result<R, GE>,
1562    H: FnMut() -> R,
1563    E: ParserError<I> + FromExternalError<I, GE>,
1564{
1565    if min > max {
1566        return Err(ParserError::assert(
1567            input,
1568            "range should be ascending, rather than descending",
1569        ));
1570    }
1571
1572    let mut acc = init();
1573    for count in 0..max {
1574        let start = input.checkpoint();
1575        let len = input.eof_offset();
1576        match parse.parse_next(input) {
1577            Ok(value) => {
1578                // infinite loop check: the parser must always consume
1579                if input.eof_offset() == len {
1580                    return Err(ParserError::assert(
1581                        input,
1582                        "`repeat` parsers must always consume",
1583                    ));
1584                }
1585
1586                match fold(acc, value) {
1587                    Ok(tmp) => acc = tmp,
1588                    Err(e) => {
1589                        input.reset(&start);
1590                        let res = Err(E::from_external_error(input, e));
1591                        super::debug::trace_result("try_fold", &res);
1592                        return res;
1593                    }
1594                }
1595            }
1596            //FInputXMError: handle failure properly
1597            Err(err) if err.is_backtrack() => {
1598                if count < min {
1599                    return Err(err.append(input, &start));
1600                } else {
1601                    input.reset(&start);
1602                    break;
1603                }
1604            }
1605            Err(e) => return Err(e),
1606        }
1607    }
1608
1609    Ok(acc)
1610}