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