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