Skip to main content

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