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