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