winnow/combinator/
multi.rs

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