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