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