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