winnow/parser.rs
1//! Basic types to build the parsers
2
3use crate::ascii::Caseless as AsciiCaseless;
4use crate::combinator::impls;
5#[cfg(feature = "unstable-recover")]
6#[cfg(feature = "std")]
7use crate::error::FromRecoverableError;
8use crate::error::{AddContext, FromExternalError, ParseError, ParserError, Result};
9use crate::stream::{Compare, Location, ParseSlice, Stream, StreamIsPartial};
10#[cfg(feature = "unstable-recover")]
11#[cfg(feature = "std")]
12use crate::stream::{Recover, Recoverable};
13
14/// Core trait for parsing
15///
16/// The simplest way to implement a `Parser` is with a function
17/// ```rust
18/// use winnow::prelude::*;
19///
20/// fn empty(input: &mut &str) -> ModalResult<()> {
21/// let output = ();
22/// Ok(output)
23/// }
24///
25/// let (input, output) = empty.parse_peek("Hello").unwrap();
26/// assert_eq!(input, "Hello"); // We didn't consume any input
27/// ```
28///
29/// which can be made stateful by returning a function
30/// ```rust
31/// use winnow::prelude::*;
32///
33/// fn empty<O: Clone>(output: O) -> impl FnMut(&mut &str) -> ModalResult<O> {
34/// move |input: &mut &str| {
35/// let output = output.clone();
36/// Ok(output)
37/// }
38/// }
39///
40/// let (input, output) = empty("World").parse_peek("Hello").unwrap();
41/// assert_eq!(input, "Hello"); // We didn't consume any input
42/// assert_eq!(output, "World");
43/// ```
44///
45/// Additionally, some basic types implement `Parser` as well, including
46/// - `u8` and `char`, see [`winnow::token::one_of`][crate::token::one_of]
47/// - `&[u8]` and `&str`, see [`winnow::token::literal`][crate::token::literal]
48pub trait Parser<I, O, E> {
49 /// Parse all of `input`, generating `O` from it
50 #[inline]
51 fn parse(&mut self, mut input: I) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>>
52 where
53 Self: core::marker::Sized,
54 I: Stream,
55 // Force users to deal with `Incomplete` when `StreamIsPartial<true>`
56 I: StreamIsPartial,
57 E: ParserError<I>,
58 <E as ParserError<I>>::Inner: ParserError<I>,
59 {
60 debug_assert!(
61 !I::is_partial_supported(),
62 "partial streams need to handle `ErrMode::Incomplete`"
63 );
64
65 let start = input.checkpoint();
66 let (o, _) = (self.by_ref(), crate::combinator::eof)
67 .parse_next(&mut input)
68 .map_err(|e| {
69 let e = e.into_inner().unwrap_or_else(|_err| {
70 panic!("complete parsers should not report `ErrMode::Incomplete(_)`")
71 });
72 ParseError::new(input, start, e)
73 })?;
74 Ok(o)
75 }
76
77 /// Take tokens from the [`Stream`], turning it into the output
78 ///
79 /// This includes advancing the [`Stream`] to the next location.
80 ///
81 /// On error, `input` will be left pointing at the error location.
82 fn parse_next(&mut self, input: &mut I) -> Result<O, E>;
83
84 /// Take tokens from the [`Stream`], turning it into the output
85 ///
86 /// This returns a copy of the [`Stream`] advanced to the next location.
87 ///
88 /// <div class="warning">
89 ///
90 /// Generally, prefer [`Parser::parse_next`].
91 /// This is primarily intended for:
92 /// - Migrating from older versions / `nom`
93 /// - Testing [`Parser`]s
94 ///
95 /// For look-ahead parsing, see instead [`peek`][crate::combinator::peek].
96 ///
97 /// </div>
98 #[inline(always)]
99 fn parse_peek(&mut self, mut input: I) -> Result<(I, O), E> {
100 match self.parse_next(&mut input) {
101 Ok(o) => Ok((input, o)),
102 Err(err) => Err(err),
103 }
104 }
105
106 /// Treat `&mut Self` as a parser
107 ///
108 /// This helps when needing to move a `Parser` when all you have is a `&mut Parser`.
109 ///
110 /// # Example
111 ///
112 /// Because parsers are `FnMut`, they can be called multiple times. This prevents moving `f`
113 /// into [`length_take`][crate::binary::length_take] and `g` into
114 /// [`Parser::complete_err`]:
115 /// ```rust,compile_fail
116 /// # use winnow::prelude::*;
117 /// # use winnow::Parser;
118 /// # use winnow::error::ParserError;
119 /// # use winnow::binary::length_take;
120 /// pub fn length_value<'i, O, E: ParserError<&'i [u8]>>(
121 /// mut f: impl Parser<&'i [u8], usize, E>,
122 /// mut g: impl Parser<&'i [u8], O, E>
123 /// ) -> impl Parser<&'i [u8], O, E> {
124 /// move |i: &mut &'i [u8]| {
125 /// let mut data = length_take(f).parse_next(i)?;
126 /// let o = g.complete_err().parse_next(&mut data)?;
127 /// Ok(o)
128 /// }
129 /// }
130 /// ```
131 ///
132 /// By adding `by_ref`, we can make this work:
133 /// ```rust
134 /// # use winnow::prelude::*;
135 /// # use winnow::Parser;
136 /// # use winnow::error::ParserError;
137 /// # use winnow::binary::length_take;
138 /// pub fn length_value<'i, O, E: ParserError<&'i [u8]>>(
139 /// mut f: impl Parser<&'i [u8], usize, E>,
140 /// mut g: impl Parser<&'i [u8], O, E>
141 /// ) -> impl Parser<&'i [u8], O, E> {
142 /// move |i: &mut &'i [u8]| {
143 /// let mut data = length_take(f.by_ref()).parse_next(i)?;
144 /// let o = g.by_ref().complete_err().parse_next(&mut data)?;
145 /// Ok(o)
146 /// }
147 /// }
148 /// ```
149 #[inline(always)]
150 fn by_ref(&mut self) -> impls::ByRef<'_, Self, I, O, E>
151 where
152 Self: core::marker::Sized,
153 {
154 impls::ByRef {
155 p: self,
156 i: Default::default(),
157 o: Default::default(),
158 e: Default::default(),
159 }
160 }
161
162 /// Produce the provided value
163 ///
164 /// # Example
165 ///
166 /// ```rust
167 /// # use winnow::{error::ErrMode, Parser};
168 /// # use winnow::prelude::*;
169 /// use winnow::ascii::alpha1;
170 /// # fn main() {
171 ///
172 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<i32> {
173 /// alpha1.value(1234).parse_next(input)
174 /// }
175 ///
176 /// assert_eq!(parser.parse_peek("abcd"), Ok(("", 1234)));
177 /// assert!(parser.parse_peek("123abcd;").is_err());
178 /// # }
179 /// ```
180 #[doc(alias = "to")]
181 #[inline(always)]
182 fn value<O2>(self, val: O2) -> impls::Value<Self, I, O, O2, E>
183 where
184 Self: core::marker::Sized,
185 O2: Clone,
186 {
187 impls::Value {
188 parser: self,
189 val,
190 i: Default::default(),
191 o: Default::default(),
192 e: Default::default(),
193 }
194 }
195
196 /// Produce a type's default value
197 ///
198 /// # Example
199 ///
200 /// ```rust
201 /// # use winnow::{error::ErrMode, Parser};
202 /// # use winnow::prelude::*;
203 /// use winnow::ascii::alpha1;
204 /// # fn main() {
205 ///
206 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<u32> {
207 /// alpha1.default_value().parse_next(input)
208 /// }
209 ///
210 /// assert_eq!(parser.parse_peek("abcd"), Ok(("", 0)));
211 /// assert!(parser.parse_peek("123abcd;").is_err());
212 /// # }
213 /// ```
214 #[inline(always)]
215 fn default_value<O2>(self) -> impls::DefaultValue<Self, I, O, O2, E>
216 where
217 Self: core::marker::Sized,
218 O2: core::default::Default,
219 {
220 impls::DefaultValue {
221 parser: self,
222 o2: Default::default(),
223 i: Default::default(),
224 o: Default::default(),
225 e: Default::default(),
226 }
227 }
228
229 /// Discards the output of the `Parser`
230 ///
231 /// # Example
232 ///
233 /// ```rust
234 /// # use winnow::{error::ErrMode, Parser};
235 /// # use winnow::prelude::*;
236 /// use winnow::ascii::alpha1;
237 /// # fn main() {
238 ///
239 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<()> {
240 /// alpha1.void().parse_next(input)
241 /// }
242 ///
243 /// assert_eq!(parser.parse_peek("abcd"), Ok(("", ())));
244 /// assert!(parser.parse_peek("123abcd;").is_err());
245 /// # }
246 /// ```
247 #[inline(always)]
248 fn void(self) -> impls::Void<Self, I, O, E>
249 where
250 Self: core::marker::Sized,
251 {
252 impls::Void {
253 parser: self,
254 i: Default::default(),
255 o: Default::default(),
256 e: Default::default(),
257 }
258 }
259
260 /// Convert the parser's output to another type using [`std::convert::From`]
261 ///
262 /// # Example
263 ///
264 /// ```rust
265 /// # use winnow::prelude::*;
266 /// # use winnow::error::ContextError;
267 /// use winnow::ascii::alpha1;
268 /// # fn main() {
269 ///
270 /// fn parser1<'s>(i: &mut &'s str) -> ModalResult<&'s str> {
271 /// alpha1(i)
272 /// }
273 ///
274 /// let mut parser2 = parser1.output_into();
275 ///
276 /// // the parser converts the &str output of the child parser into a Vec<u8>
277 /// let bytes: ModalResult<(_, Vec<u8>), _> = parser2.parse_peek("abcd");
278 /// assert_eq!(bytes, Ok(("", vec![97, 98, 99, 100])));
279 /// # }
280 /// ```
281 #[inline(always)]
282 fn output_into<O2>(self) -> impls::OutputInto<Self, I, O, O2, E>
283 where
284 Self: core::marker::Sized,
285 O: Into<O2>,
286 {
287 impls::OutputInto {
288 parser: self,
289 i: Default::default(),
290 o: Default::default(),
291 o2: Default::default(),
292 e: Default::default(),
293 }
294 }
295
296 /// Produce the consumed input as produced value.
297 ///
298 /// # Example
299 ///
300 /// ```rust
301 /// # use winnow::{error::ErrMode, Parser};
302 /// # use winnow::prelude::*;
303 /// use winnow::ascii::{alpha1};
304 /// use winnow::combinator::separated_pair;
305 /// # fn main() {
306 ///
307 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
308 /// separated_pair(alpha1, ',', alpha1).take().parse_next(input)
309 /// }
310 ///
311 /// assert_eq!(parser.parse_peek("abcd,efgh"), Ok(("", "abcd,efgh")));
312 /// assert!(parser.parse_peek("abcd;").is_err());
313 /// # }
314 /// ```
315 #[doc(alias = "concat")]
316 #[doc(alias = "recognize")]
317 #[inline(always)]
318 fn take(self) -> impls::Take<Self, I, O, E>
319 where
320 Self: core::marker::Sized,
321 I: Stream,
322 {
323 impls::Take {
324 parser: self,
325 i: Default::default(),
326 o: Default::default(),
327 e: Default::default(),
328 }
329 }
330
331 /// Produce the consumed input with the output
332 ///
333 /// Functions similarly to [take][Parser::take] except it
334 /// returns the parser output as well.
335 ///
336 /// This can be useful especially in cases where the output is not the same type
337 /// as the input, or the input is a user defined type.
338 ///
339 /// Returned tuple is of the format `(produced output, consumed input)`.
340 ///
341 /// # Example
342 ///
343 /// ```rust
344 /// # use winnow::prelude::*;
345 /// # use winnow::{error::ErrMode};
346 /// use winnow::ascii::{alpha1};
347 /// use winnow::token::literal;
348 /// use winnow::combinator::separated_pair;
349 ///
350 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<(bool, &'i str)> {
351 /// separated_pair(alpha1, ',', alpha1).value(true).with_taken().parse_next(input)
352 /// }
353 ///
354 /// assert_eq!(parser.parse_peek("abcd,efgh1"), Ok(("1", (true, "abcd,efgh"))));
355 /// assert!(parser.parse_peek("abcd;").is_err());
356 /// ```
357 #[doc(alias = "consumed")]
358 #[doc(alias = "with_recognized")]
359 #[inline(always)]
360 fn with_taken(self) -> impls::WithTaken<Self, I, O, E>
361 where
362 Self: core::marker::Sized,
363 I: Stream,
364 {
365 impls::WithTaken {
366 parser: self,
367 i: Default::default(),
368 o: Default::default(),
369 e: Default::default(),
370 }
371 }
372
373 /// Produce the location of the consumed input as produced value.
374 ///
375 /// # Example
376 ///
377 /// ```rust
378 /// # use winnow::prelude::*;
379 /// # use winnow::{error::ErrMode, stream::Stream};
380 /// # use std::ops::Range;
381 /// use winnow::stream::LocatingSlice;
382 /// use winnow::ascii::alpha1;
383 /// use winnow::combinator::separated_pair;
384 ///
385 /// fn parser<'i>(input: &mut LocatingSlice<&'i str>) -> ModalResult<(Range<usize>, Range<usize>)> {
386 /// separated_pair(alpha1.span(), ',', alpha1.span()).parse_next(input)
387 /// }
388 ///
389 /// assert_eq!(parser.parse(LocatingSlice::new("abcd,efgh")), Ok((0..4, 5..9)));
390 /// assert!(parser.parse_peek(LocatingSlice::new("abcd;")).is_err());
391 /// ```
392 #[inline(always)]
393 fn span(self) -> impls::Span<Self, I, O, E>
394 where
395 Self: core::marker::Sized,
396 I: Stream + Location,
397 {
398 impls::Span {
399 parser: self,
400 i: Default::default(),
401 o: Default::default(),
402 e: Default::default(),
403 }
404 }
405
406 /// Produce the location of consumed input with the output
407 ///
408 /// Functions similarly to [`Parser::span`] except it
409 /// returns the parser output as well.
410 ///
411 /// This can be useful especially in cases where the output is not the same type
412 /// as the input, or the input is a user defined type.
413 ///
414 /// Returned tuple is of the format `(produced output, consumed input)`.
415 ///
416 /// # Example
417 ///
418 /// ```rust
419 /// # use winnow::prelude::*;
420 /// # use winnow::{error::ErrMode, stream::Stream};
421 /// # use std::ops::Range;
422 /// use winnow::stream::LocatingSlice;
423 /// use winnow::ascii::alpha1;
424 /// use winnow::token::literal;
425 /// use winnow::combinator::separated_pair;
426 ///
427 /// fn parser<'i>(input: &mut LocatingSlice<&'i str>) -> ModalResult<((usize, Range<usize>), (usize, Range<usize>))> {
428 /// separated_pair(alpha1.value(1).with_span(), ',', alpha1.value(2).with_span()).parse_next(input)
429 /// }
430 ///
431 /// assert_eq!(parser.parse(LocatingSlice::new("abcd,efgh")), Ok(((1, 0..4), (2, 5..9))));
432 /// assert!(parser.parse_peek(LocatingSlice::new("abcd;")).is_err());
433 /// ```
434 #[inline(always)]
435 fn with_span(self) -> impls::WithSpan<Self, I, O, E>
436 where
437 Self: core::marker::Sized,
438 I: Stream + Location,
439 {
440 impls::WithSpan {
441 parser: self,
442 i: Default::default(),
443 o: Default::default(),
444 e: Default::default(),
445 }
446 }
447
448 /// Maps a function over the output of a parser
449 ///
450 /// # Example
451 ///
452 /// ```rust
453 /// # use winnow::prelude::*;
454 /// # use winnow::{error::ErrMode, Parser};
455 /// # use winnow::ascii::digit1;
456 /// # fn main() {
457 ///
458 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<usize> {
459 /// digit1.map(|s: &str| s.len()).parse_next(input)
460 /// }
461 ///
462 /// // the parser will count how many characters were returned by digit1
463 /// assert_eq!(parser.parse_peek("123456"), Ok(("", 6)));
464 ///
465 /// // this will fail if digit1 fails
466 /// assert!(parser.parse_peek("abc").is_err());
467 /// # }
468 /// ```
469 #[inline(always)]
470 fn map<G, O2>(self, map: G) -> impls::Map<Self, G, I, O, O2, E>
471 where
472 G: FnMut(O) -> O2,
473 Self: core::marker::Sized,
474 {
475 impls::Map {
476 parser: self,
477 map,
478 i: Default::default(),
479 o: Default::default(),
480 o2: Default::default(),
481 e: Default::default(),
482 }
483 }
484
485 /// Applies a function returning a `Result` over the output of a parser.
486 ///
487 /// # Example
488 ///
489 /// ```rust
490 /// # use winnow::{error::ErrMode, Parser};
491 /// # use winnow::prelude::*;
492 /// use winnow::ascii::digit1;
493 /// # fn main() {
494 ///
495 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<u8> {
496 /// digit1.try_map(|s: &str| s.parse::<u8>()).parse_next(input)
497 /// }
498 ///
499 /// // the parser will convert the result of digit1 to a number
500 /// assert_eq!(parser.parse_peek("123"), Ok(("", 123)));
501 ///
502 /// // this will fail if digit1 fails
503 /// assert!(parser.parse_peek("abc").is_err());
504 ///
505 /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
506 /// assert!(parser.parse_peek("123456").is_err());
507 /// # }
508 /// ```
509 #[inline(always)]
510 fn try_map<G, O2, E2>(self, map: G) -> impls::TryMap<Self, G, I, O, O2, E, E2>
511 where
512 Self: core::marker::Sized,
513 G: FnMut(O) -> Result<O2, E2>,
514 I: Stream,
515 E: FromExternalError<I, E2>,
516 E: ParserError<I>,
517 {
518 impls::TryMap {
519 parser: self,
520 map,
521 i: Default::default(),
522 o: Default::default(),
523 o2: Default::default(),
524 e: Default::default(),
525 e2: Default::default(),
526 }
527 }
528
529 /// Apply both [`Parser::verify`] and [`Parser::map`].
530 ///
531 /// # Example
532 ///
533 /// ```rust
534 /// # use winnow::{error::ErrMode, Parser};
535 /// # use winnow::prelude::*;
536 /// use winnow::ascii::digit1;
537 /// # fn main() {
538 ///
539 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<u8> {
540 /// digit1.verify_map(|s: &str| s.parse::<u8>().ok()).parse_next(input)
541 /// }
542 ///
543 /// // the parser will convert the result of digit1 to a number
544 /// assert_eq!(parser.parse_peek("123"), Ok(("", 123)));
545 ///
546 /// // this will fail if digit1 fails
547 /// assert!(parser.parse_peek("abc").is_err());
548 ///
549 /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
550 /// assert!(parser.parse_peek("123456").is_err());
551 /// # }
552 /// ```
553 #[doc(alias = "satisfy_map")]
554 #[doc(alias = "filter_map")]
555 #[doc(alias = "map_opt")]
556 #[inline(always)]
557 fn verify_map<G, O2>(self, map: G) -> impls::VerifyMap<Self, G, I, O, O2, E>
558 where
559 Self: core::marker::Sized,
560 G: FnMut(O) -> Option<O2>,
561 I: Stream,
562 E: ParserError<I>,
563 {
564 impls::VerifyMap {
565 parser: self,
566 map,
567 i: Default::default(),
568 o: Default::default(),
569 o2: Default::default(),
570 e: Default::default(),
571 }
572 }
573
574 /// Creates a parser from the output of this one
575 ///
576 /// # Example
577 ///
578 /// ```rust
579 /// # use winnow::{error::ErrMode, ModalResult, Parser};
580 /// use winnow::token::take;
581 /// use winnow::binary::u8;
582 ///
583 /// fn length_take<'s>(input: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
584 /// u8.flat_map(take).parse_next(input)
585 /// }
586 ///
587 /// assert_eq!(length_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
588 /// assert!(length_take.parse_peek(&[4, 0, 1, 2][..]).is_err());
589 /// ```
590 ///
591 /// which is the same as
592 /// ```rust
593 /// # use winnow::{error::ErrMode, ModalResult, Parser};
594 /// use winnow::token::take;
595 /// use winnow::binary::u8;
596 ///
597 /// fn length_take<'s>(input: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
598 /// let length = u8.parse_next(input)?;
599 /// let data = take(length).parse_next(input)?;
600 /// Ok(data)
601 /// }
602 ///
603 /// assert_eq!(length_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
604 /// assert!(length_take.parse_peek(&[4, 0, 1, 2][..]).is_err());
605 /// ```
606 #[inline(always)]
607 fn flat_map<G, H, O2>(self, map: G) -> impls::FlatMap<Self, G, H, I, O, O2, E>
608 where
609 Self: core::marker::Sized,
610 G: FnMut(O) -> H,
611 H: Parser<I, O2, E>,
612 {
613 impls::FlatMap {
614 f: self,
615 g: map,
616 h: Default::default(),
617 i: Default::default(),
618 o: Default::default(),
619 o2: Default::default(),
620 e: Default::default(),
621 }
622 }
623
624 /// Applies a second parser over the output of the first one
625 ///
626 /// # Example
627 ///
628 /// ```rust
629 /// # use winnow::{error::ErrMode, Parser};
630 /// # use winnow::prelude::*;
631 /// use winnow::ascii::digit1;
632 /// use winnow::token::take;
633 /// # fn main() {
634 ///
635 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
636 /// take(5u8).and_then(digit1).parse_next(input)
637 /// }
638 ///
639 /// assert_eq!(parser.parse_peek("12345"), Ok(("", "12345")));
640 /// assert_eq!(parser.parse_peek("123ab"), Ok(("", "123")));
641 /// assert!(parser.parse_peek("123").is_err());
642 /// # }
643 /// ```
644 #[inline(always)]
645 fn and_then<G, O2>(self, inner: G) -> impls::AndThen<Self, G, I, O, O2, E>
646 where
647 Self: core::marker::Sized,
648 G: Parser<O, O2, E>,
649 O: StreamIsPartial,
650 I: Stream,
651 {
652 impls::AndThen {
653 outer: self,
654 inner,
655 i: Default::default(),
656 o: Default::default(),
657 o2: Default::default(),
658 e: Default::default(),
659 }
660 }
661
662 /// Apply [`std::str::FromStr`] to the output of the parser
663 ///
664 /// # Example
665 ///
666 /// ```rust
667 /// # use winnow::prelude::*;
668 /// use winnow::{error::ErrMode, Parser};
669 /// use winnow::ascii::digit1;
670 ///
671 /// fn parser<'s>(input: &mut &'s str) -> ModalResult<u64> {
672 /// digit1.parse_to().parse_next(input)
673 /// }
674 ///
675 /// // the parser will count how many characters were returned by digit1
676 /// assert_eq!(parser.parse_peek("123456"), Ok(("", 123456)));
677 ///
678 /// // this will fail if digit1 fails
679 /// assert!(parser.parse_peek("abc").is_err());
680 /// ```
681 #[doc(alias = "from_str")]
682 #[inline(always)]
683 fn parse_to<O2>(self) -> impls::ParseTo<Self, I, O, O2, E>
684 where
685 Self: core::marker::Sized,
686 I: Stream,
687 O: ParseSlice<O2>,
688 E: ParserError<I>,
689 {
690 impls::ParseTo {
691 p: self,
692 i: Default::default(),
693 o: Default::default(),
694 o2: Default::default(),
695 e: Default::default(),
696 }
697 }
698
699 /// Returns the output of the child parser if it satisfies a verification function.
700 ///
701 /// The verification function takes as argument a reference to the output of the
702 /// parser.
703 ///
704 /// # Example
705 ///
706 /// ```rust
707 /// # use winnow::{error::ErrMode, Parser};
708 /// # use winnow::ascii::alpha1;
709 /// # use winnow::prelude::*;
710 /// # fn main() {
711 ///
712 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
713 /// alpha1.verify(|s: &str| s.len() == 4).parse_next(input)
714 /// }
715 ///
716 /// assert_eq!(parser.parse_peek("abcd"), Ok(("", "abcd")));
717 /// assert!(parser.parse_peek("abcde").is_err());
718 /// assert!(parser.parse_peek("123abcd;").is_err());
719 /// # }
720 /// ```
721 #[doc(alias = "satisfy")]
722 #[doc(alias = "filter")]
723 #[inline(always)]
724 fn verify<G, O2>(self, filter: G) -> impls::Verify<Self, G, I, O, O2, E>
725 where
726 Self: core::marker::Sized,
727 G: FnMut(&O2) -> bool,
728 I: Stream,
729 O: crate::lib::std::borrow::Borrow<O2>,
730 O2: ?Sized,
731 E: ParserError<I>,
732 {
733 impls::Verify {
734 parser: self,
735 filter,
736 i: Default::default(),
737 o: Default::default(),
738 o2: Default::default(),
739 e: Default::default(),
740 }
741 }
742
743 /// If parsing fails, add context to the error
744 ///
745 /// This is used mainly to add user friendly information
746 /// to errors when backtracking through a parse tree.
747 ///
748 /// See also [tutorial][crate::_tutorial::chapter_7].
749 ///
750 /// # Example
751 ///
752 /// ```rust
753 /// # use winnow::prelude::*;
754 /// # use winnow::{error::ErrMode, Parser};
755 /// # use winnow::ascii::digit1;
756 /// # use winnow::error::StrContext;
757 /// # use winnow::error::StrContextValue;
758 /// # fn main() {
759 ///
760 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
761 /// digit1
762 /// .context(StrContext::Expected(StrContextValue::Description("digit")))
763 /// .parse_next(input)
764 /// }
765 ///
766 /// assert_eq!(parser.parse_peek("123456"), Ok(("", "123456")));
767 /// assert!(parser.parse_peek("abc").is_err());
768 /// # }
769 /// ```
770 #[doc(alias = "labelled")]
771 #[inline(always)]
772 fn context<C>(self, context: C) -> impls::Context<Self, I, O, E, C>
773 where
774 Self: core::marker::Sized,
775 I: Stream,
776 E: AddContext<I, C>,
777 E: ParserError<I>,
778 C: Clone + crate::lib::std::fmt::Debug,
779 {
780 impls::Context {
781 parser: self,
782 context,
783 i: Default::default(),
784 o: Default::default(),
785 e: Default::default(),
786 }
787 }
788
789 /// If parsing fails, dynamically add context to the error
790 ///
791 /// This is used mainly to add user friendly information
792 /// to errors when backtracking through a parse tree.
793 ///
794 /// See also [tutorial][crate::_tutorial::chapter_7].
795 ///
796 /// # Example
797 ///
798 /// ```rust
799 /// # use winnow::prelude::*;
800 /// # use winnow::{error::ErrMode, Parser};
801 /// # use winnow::ascii::digit1;
802 /// # use winnow::error::StrContext;
803 /// # use winnow::error::StrContextValue;
804 /// # fn main() {
805 ///
806 /// fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
807 /// digit1
808 /// .context_with(|| {
809 /// "0123456789".chars().map(|c| StrContext::Expected(c.into()))
810 /// })
811 /// .parse_next(input)
812 /// }
813 ///
814 /// assert_eq!(parser.parse_peek("123456"), Ok(("", "123456")));
815 /// assert!(parser.parse_peek("abc").is_err());
816 /// # }
817 /// ```
818 #[doc(alias = "labelled")]
819 #[inline(always)]
820 fn context_with<F, C, FI>(self, context: F) -> impls::ContextWith<Self, I, O, E, F, C, FI>
821 where
822 Self: core::marker::Sized,
823 I: Stream,
824 E: AddContext<I, C>,
825 E: ParserError<I>,
826 F: Fn() -> FI + Clone,
827 C: crate::lib::std::fmt::Debug,
828 FI: Iterator<Item = C>,
829 {
830 impls::ContextWith {
831 parser: self,
832 context,
833 i: Default::default(),
834 o: Default::default(),
835 e: Default::default(),
836 c: Default::default(),
837 fi: Default::default(),
838 }
839 }
840
841 /// Maps a function over the error of a parser
842 ///
843 /// # Example
844 ///
845 /// ```rust
846 /// # use winnow::prelude::*;
847 /// # use winnow::Parser;
848 /// # use winnow::Result;
849 /// # use winnow::ascii::digit1;
850 /// # use winnow::error::StrContext;
851 /// # use winnow::error::AddContext;
852 /// # use winnow::error::ContextError;
853 /// # fn main() {
854 ///
855 /// fn parser<'i>(input: &mut &'i str) -> Result<&'i str> {
856 /// digit1.map_err(|mut e: ContextError| {
857 /// e.extend("0123456789".chars().map(|c| StrContext::Expected(c.into())));
858 /// e
859 /// }).parse_next(input)
860 /// }
861 ///
862 /// assert_eq!(parser.parse_peek("123456"), Ok(("", "123456")));
863 /// assert!(parser.parse_peek("abc").is_err());
864 /// # }
865 /// ```
866 #[inline(always)]
867 fn map_err<G, E2>(self, map: G) -> impls::MapErr<Self, G, I, O, E, E2>
868 where
869 G: FnMut(E) -> E2,
870 Self: core::marker::Sized,
871 {
872 impls::MapErr {
873 parser: self,
874 map,
875 i: Default::default(),
876 o: Default::default(),
877 e: Default::default(),
878 e2: Default::default(),
879 }
880 }
881
882 /// Transforms [`Incomplete`][crate::error::ErrMode::Incomplete] into [`Backtrack`][crate::error::ErrMode::Backtrack]
883 ///
884 /// # Example
885 ///
886 /// ```rust
887 /// # use winnow::{error::ErrMode, error::InputError, stream::Partial, Parser};
888 /// # use winnow::token::take;
889 /// # use winnow::prelude::*;
890 /// # fn main() {
891 ///
892 /// fn parser<'i>(input: &mut Partial<&'i str>) -> ModalResult<&'i str, InputError<Partial<&'i str>>> {
893 /// take(5u8).complete_err().parse_next(input)
894 /// }
895 ///
896 /// assert_eq!(parser.parse_peek(Partial::new("abcdefg")), Ok((Partial::new("fg"), "abcde")));
897 /// assert_eq!(parser.parse_peek(Partial::new("abcd")), Err(ErrMode::Backtrack(InputError::at(Partial::new("abcd")))));
898 /// # }
899 /// ```
900 #[inline(always)]
901 fn complete_err(self) -> impls::CompleteErr<Self, I, O, E>
902 where
903 Self: core::marker::Sized,
904 {
905 impls::CompleteErr {
906 p: self,
907 i: Default::default(),
908 o: Default::default(),
909 e: Default::default(),
910 }
911 }
912
913 /// Convert the parser's error to another type using [`std::convert::From`]
914 #[inline(always)]
915 fn err_into<E2>(self) -> impls::ErrInto<Self, I, O, E, E2>
916 where
917 Self: core::marker::Sized,
918 E: Into<E2>,
919 {
920 impls::ErrInto {
921 parser: self,
922 i: Default::default(),
923 o: Default::default(),
924 e: Default::default(),
925 e2: Default::default(),
926 }
927 }
928
929 /// Recover from an error by skipping everything `recover` consumes and trying again
930 ///
931 /// If `recover` consumes nothing, the error is returned, allowing an alternative recovery
932 /// method.
933 ///
934 /// This commits the parse result, preventing alternative branch paths like with
935 /// [`winnow::combinator::alt`][crate::combinator::alt].
936 #[inline(always)]
937 #[cfg(feature = "unstable-recover")]
938 #[cfg(feature = "std")]
939 fn retry_after<R>(self, recover: R) -> impls::RetryAfter<Self, R, I, O, E>
940 where
941 Self: core::marker::Sized,
942 R: Parser<I, (), E>,
943 I: Stream,
944 I: Recover<E>,
945 E: ParserError<I> + FromRecoverableError<I, E>,
946 {
947 impls::RetryAfter {
948 parser: self,
949 recover,
950 i: Default::default(),
951 o: Default::default(),
952 e: Default::default(),
953 }
954 }
955
956 /// Recover from an error by skipping this parse and everything `recover` consumes
957 ///
958 /// This commits the parse result, preventing alternative branch paths like with
959 /// [`winnow::combinator::alt`][crate::combinator::alt].
960 #[inline(always)]
961 #[cfg(feature = "unstable-recover")]
962 #[cfg(feature = "std")]
963 fn resume_after<R>(self, recover: R) -> impls::ResumeAfter<Self, R, I, O, E>
964 where
965 Self: core::marker::Sized,
966 R: Parser<I, (), E>,
967 I: Stream,
968 I: Recover<E>,
969 E: ParserError<I> + FromRecoverableError<I, E>,
970 {
971 impls::ResumeAfter {
972 parser: self,
973 recover,
974 i: Default::default(),
975 o: Default::default(),
976 e: Default::default(),
977 }
978 }
979}
980
981impl<I, O, E, F> Parser<I, O, E> for F
982where
983 F: FnMut(&mut I) -> Result<O, E>,
984 I: Stream,
985{
986 #[inline(always)]
987 fn parse_next(&mut self, i: &mut I) -> Result<O, E> {
988 self(i)
989 }
990}
991
992/// This is a shortcut for [`one_of`][crate::token::one_of].
993///
994/// # Example
995///
996/// ```rust
997/// # use winnow::prelude::*;
998/// # use winnow::{error::ErrMode, error::ContextError};
999/// fn parser<'s>(i: &mut &'s [u8]) -> ModalResult<u8> {
1000/// b'a'.parse_next(i)
1001/// }
1002/// assert_eq!(parser.parse_peek(&b"abc"[..]), Ok((&b"bc"[..], b'a')));
1003/// assert!(parser.parse_peek(&b" abc"[..]).is_err());
1004/// assert!(parser.parse_peek(&b"bc"[..]).is_err());
1005/// assert!(parser.parse_peek(&b""[..]).is_err());
1006/// ```
1007impl<I, E> Parser<I, u8, E> for u8
1008where
1009 I: StreamIsPartial,
1010 I: Stream,
1011 I: Compare<u8>,
1012 E: ParserError<I>,
1013{
1014 #[inline(always)]
1015 fn parse_next(&mut self, i: &mut I) -> Result<u8, E> {
1016 crate::token::literal(*self).value(*self).parse_next(i)
1017 }
1018}
1019
1020/// This is a shortcut for [`one_of`][crate::token::one_of].
1021///
1022/// # Example
1023///
1024/// ```rust
1025/// # use winnow::prelude::*;
1026/// # use winnow::{error::ErrMode, error::ContextError};
1027/// fn parser<'s>(i: &mut &'s str) -> ModalResult<char> {
1028/// 'a'.parse_next(i)
1029/// }
1030/// assert_eq!(parser.parse_peek("abc"), Ok(("bc", 'a')));
1031/// assert!(parser.parse_peek(" abc").is_err());
1032/// assert!(parser.parse_peek("bc").is_err());
1033/// assert!(parser.parse_peek("").is_err());
1034/// ```
1035impl<I, E> Parser<I, char, E> for char
1036where
1037 I: StreamIsPartial,
1038 I: Stream,
1039 I: Compare<char>,
1040 E: ParserError<I>,
1041{
1042 #[inline(always)]
1043 fn parse_next(&mut self, i: &mut I) -> Result<char, E> {
1044 crate::token::literal(*self).value(*self).parse_next(i)
1045 }
1046}
1047
1048/// This is a shortcut for [`literal`][crate::token::literal].
1049///
1050/// # Example
1051/// ```rust
1052/// # use winnow::prelude::*;
1053/// # use winnow::{error::ErrMode, error::ContextError, error::Needed};
1054/// # use winnow::combinator::alt;
1055/// # use winnow::token::take;
1056///
1057/// fn parser<'s>(s: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
1058/// alt((&"Hello"[..], take(5usize))).parse_next(s)
1059/// }
1060///
1061/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
1062/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
1063/// assert!(parser.parse_peek(&b"Some"[..]).is_err());
1064/// assert!(parser.parse_peek(&b""[..]).is_err());
1065/// ```
1066impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8]
1067where
1068 I: Compare<&'s [u8]> + StreamIsPartial,
1069 I: Stream,
1070{
1071 #[inline(always)]
1072 fn parse_next(&mut self, i: &mut I) -> Result<<I as Stream>::Slice, E> {
1073 crate::token::literal(*self).parse_next(i)
1074 }
1075}
1076
1077/// This is a shortcut for [`literal`][crate::token::literal].
1078///
1079/// # Example
1080/// ```rust
1081/// # use winnow::prelude::*;
1082/// # use winnow::{error::ErrMode, error::ContextError, error::Needed};
1083/// # use winnow::combinator::alt;
1084/// # use winnow::token::take;
1085/// use winnow::ascii::Caseless;
1086///
1087/// fn parser<'s>(s: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
1088/// alt((Caseless(&"hello"[..]), take(5usize))).parse_next(s)
1089/// }
1090///
1091/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
1092/// assert_eq!(parser.parse_peek(&b"hello, World!"[..]), Ok((&b", World!"[..], &b"hello"[..])));
1093/// assert_eq!(parser.parse_peek(&b"HeLlo, World!"[..]), Ok((&b", World!"[..], &b"HeLlo"[..])));
1094/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
1095/// assert!(parser.parse_peek(&b"Some"[..]).is_err());
1096/// assert!(parser.parse_peek(&b""[..]).is_err());
1097/// ```
1098impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s [u8]>
1099where
1100 I: Compare<AsciiCaseless<&'s [u8]>> + StreamIsPartial,
1101 I: Stream,
1102{
1103 #[inline(always)]
1104 fn parse_next(&mut self, i: &mut I) -> Result<<I as Stream>::Slice, E> {
1105 crate::token::literal(*self).parse_next(i)
1106 }
1107}
1108
1109/// This is a shortcut for [`literal`][crate::token::literal].
1110///
1111/// # Example
1112/// ```rust
1113/// # use winnow::prelude::*;
1114/// # use winnow::{error::ErrMode, error::ContextError, error::Needed};
1115/// # use winnow::combinator::alt;
1116/// # use winnow::token::take;
1117///
1118/// fn parser<'s>(s: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
1119/// alt((b"Hello", take(5usize))).parse_next(s)
1120/// }
1121///
1122/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
1123/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
1124/// assert!(parser.parse_peek(&b"Some"[..]).is_err());
1125/// assert!(parser.parse_peek(&b""[..]).is_err());
1126/// ```
1127impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N]
1128where
1129 I: Compare<&'s [u8; N]> + StreamIsPartial,
1130 I: Stream,
1131{
1132 #[inline(always)]
1133 fn parse_next(&mut self, i: &mut I) -> Result<<I as Stream>::Slice, E> {
1134 crate::token::literal(*self).parse_next(i)
1135 }
1136}
1137
1138/// This is a shortcut for [`literal`][crate::token::literal].
1139///
1140/// # Example
1141/// ```rust
1142/// # use winnow::prelude::*;
1143/// # use winnow::{error::ErrMode, error::ContextError, error::Needed};
1144/// # use winnow::combinator::alt;
1145/// # use winnow::token::take;
1146/// use winnow::ascii::Caseless;
1147///
1148/// fn parser<'s>(s: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
1149/// alt((Caseless(b"hello"), take(5usize))).parse_next(s)
1150/// }
1151///
1152/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
1153/// assert_eq!(parser.parse_peek(&b"hello, World!"[..]), Ok((&b", World!"[..], &b"hello"[..])));
1154/// assert_eq!(parser.parse_peek(&b"HeLlo, World!"[..]), Ok((&b", World!"[..], &b"HeLlo"[..])));
1155/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
1156/// assert!(parser.parse_peek(&b"Some"[..]).is_err());
1157/// assert!(parser.parse_peek(&b""[..]).is_err());
1158/// ```
1159impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E>
1160 for AsciiCaseless<&'s [u8; N]>
1161where
1162 I: Compare<AsciiCaseless<&'s [u8; N]>> + StreamIsPartial,
1163 I: Stream,
1164{
1165 #[inline(always)]
1166 fn parse_next(&mut self, i: &mut I) -> Result<<I as Stream>::Slice, E> {
1167 crate::token::literal(*self).parse_next(i)
1168 }
1169}
1170
1171/// This is a shortcut for [`literal`][crate::token::literal].
1172///
1173/// # Example
1174/// ```rust
1175/// # use winnow::prelude::*;
1176/// # use winnow::{error::ErrMode, error::ContextError};
1177/// # use winnow::combinator::alt;
1178/// # use winnow::token::take;
1179///
1180/// fn parser<'s>(s: &mut &'s str) -> ModalResult<&'s str> {
1181/// alt(("Hello", take(5usize))).parse_next(s)
1182/// }
1183///
1184/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello")));
1185/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet")));
1186/// assert!(parser.parse_peek("Some").is_err());
1187/// assert!(parser.parse_peek("").is_err());
1188/// ```
1189impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str
1190where
1191 I: Compare<&'s str> + StreamIsPartial,
1192 I: Stream,
1193{
1194 #[inline(always)]
1195 fn parse_next(&mut self, i: &mut I) -> Result<<I as Stream>::Slice, E> {
1196 crate::token::literal(*self).parse_next(i)
1197 }
1198}
1199
1200/// This is a shortcut for [`literal`][crate::token::literal].
1201///
1202/// # Example
1203/// ```rust
1204/// # use winnow::prelude::*;
1205/// # use winnow::{error::ErrMode, error::ContextError};
1206/// # use winnow::combinator::alt;
1207/// # use winnow::token::take;
1208/// # use winnow::ascii::Caseless;
1209///
1210/// fn parser<'s>(s: &mut &'s str) -> ModalResult<&'s str> {
1211/// alt((Caseless("hello"), take(5usize))).parse_next(s)
1212/// }
1213///
1214/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello")));
1215/// assert_eq!(parser.parse_peek("hello, World!"), Ok((", World!", "hello")));
1216/// assert_eq!(parser.parse_peek("HeLlo, World!"), Ok((", World!", "HeLlo")));
1217/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet")));
1218/// assert!(parser.parse_peek("Some").is_err());
1219/// assert!(parser.parse_peek("").is_err());
1220/// ```
1221impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s str>
1222where
1223 I: Compare<AsciiCaseless<&'s str>> + StreamIsPartial,
1224 I: Stream,
1225{
1226 #[inline(always)]
1227 fn parse_next(&mut self, i: &mut I) -> Result<<I as Stream>::Slice, E> {
1228 crate::token::literal(*self).parse_next(i)
1229 }
1230}
1231
1232impl<I: Stream, E: ParserError<I>> Parser<I, (), E> for () {
1233 #[inline(always)]
1234 fn parse_next(&mut self, _i: &mut I) -> Result<(), E> {
1235 Ok(())
1236 }
1237}
1238
1239macro_rules! impl_parser_for_tuple {
1240 ($($index:tt $parser:ident $output:ident),+) => (
1241 #[allow(non_snake_case)]
1242 impl<I: Stream, $($output),+, E: ParserError<I>, $($parser),+> Parser<I, ($($output),+,), E> for ($($parser),+,)
1243 where
1244 $($parser: Parser<I, $output, E>),+
1245 {
1246 #[inline(always)]
1247 fn parse_next(&mut self, i: &mut I) -> Result<($($output),+,), E> {
1248 $(let $output = self.$index.parse_next(i)?;)+
1249
1250 Ok(($($output),+,))
1251 }
1252 }
1253 )
1254}
1255
1256macro_rules! impl_parser_for_tuples {
1257 ($index1:tt $parser1:ident $output1:ident, $($index:tt $parser:ident $output:ident),+) => {
1258 impl_parser_for_tuples!(__impl $index1 $parser1 $output1; $($index $parser $output),+);
1259 };
1260 (__impl $($index:tt $parser:ident $output:ident),+; $index1:tt $parser1:ident $output1:ident $(,$index2:tt $parser2:ident $output2:ident)*) => {
1261 impl_parser_for_tuple!($($index $parser $output),+);
1262 impl_parser_for_tuples!(__impl $($index $parser $output),+, $index1 $parser1 $output1; $($index2 $parser2 $output2),*);
1263 };
1264 (__impl $($index:tt $parser:ident $output:ident),+;) => {
1265 impl_parser_for_tuple!($($index $parser $output),+);
1266 }
1267}
1268
1269impl_parser_for_tuples!(
1270 0 P0 O0,
1271 1 P1 O1,
1272 2 P2 O2,
1273 3 P3 O3,
1274 4 P4 O4,
1275 5 P5 O5,
1276 6 P6 O6,
1277 7 P7 O7,
1278 8 P8 O8,
1279 9 P9 O9,
1280 10 P10 O10,
1281 11 P11 O11,
1282 12 P12 O12,
1283 13 P13 O13,
1284 14 P14 O14,
1285 15 P15 O15,
1286 16 P16 O16,
1287 17 P17 O17,
1288 18 P18 O18,
1289 19 P19 O19,
1290 20 P20 O20,
1291 21 P21 O21
1292);
1293
1294#[cfg(feature = "alloc")]
1295use crate::lib::std::boxed::Box;
1296
1297#[cfg(feature = "alloc")]
1298impl<I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + '_> {
1299 #[inline(always)]
1300 fn parse_next(&mut self, i: &mut I) -> Result<O, E> {
1301 (**self).parse_next(i)
1302 }
1303}
1304
1305/// Trait alias for [`Parser`] to be used with [`ModalResult`][crate::error::ModalResult]
1306pub trait ModalParser<I, O, E>: Parser<I, O, crate::error::ErrMode<E>> {}
1307
1308impl<I, O, E, P> ModalParser<I, O, E> for P where P: Parser<I, O, crate::error::ErrMode<E>> {}
1309
1310/// Collect all errors when parsing the input
1311///
1312/// [`Parser`]s will need to use [`Recoverable<I, _>`] for their input.
1313#[cfg(feature = "unstable-recover")]
1314#[cfg(feature = "std")]
1315pub trait RecoverableParser<I, O, R, E> {
1316 /// Collect all errors when parsing the input
1317 ///
1318 /// If `self` fails, this acts like [`Parser::resume_after`] and returns `Ok(None)`.
1319 /// Generally, this should be avoided by using
1320 /// [`Parser::retry_after`] and [`Parser::resume_after`] throughout your parser.
1321 ///
1322 /// The empty `input` is returned to allow turning the errors into [`ParserError`]s.
1323 fn recoverable_parse(&mut self, input: I) -> (I, Option<O>, Vec<R>);
1324}
1325
1326#[cfg(feature = "unstable-recover")]
1327#[cfg(feature = "std")]
1328impl<P, I, O, R, E> RecoverableParser<I, O, R, E> for P
1329where
1330 P: Parser<Recoverable<I, R>, O, E>,
1331 I: Stream,
1332 I: StreamIsPartial,
1333 R: FromRecoverableError<Recoverable<I, R>, E>,
1334 R: crate::lib::std::fmt::Debug,
1335 E: FromRecoverableError<Recoverable<I, R>, E>,
1336 E: ParserError<Recoverable<I, R>>,
1337 E: crate::lib::std::fmt::Debug,
1338{
1339 fn recoverable_parse(&mut self, input: I) -> (I, Option<O>, Vec<R>) {
1340 debug_assert!(
1341 !I::is_partial_supported(),
1342 "partial streams need to handle `ErrMode::Incomplete`"
1343 );
1344
1345 let start = input.checkpoint();
1346 let mut input = Recoverable::new(input);
1347 let start_token = input.checkpoint();
1348 let result = (
1349 self.by_ref(),
1350 crate::combinator::eof.resume_after(crate::token::rest.void()),
1351 )
1352 .parse_next(&mut input);
1353
1354 let (o, err) = match result {
1355 Ok((o, _)) => (Some(o), None),
1356 Err(err) => {
1357 let err_start = input.checkpoint();
1358 let err = R::from_recoverable_error(&start_token, &err_start, &input, err);
1359 (None, Some(err))
1360 }
1361 };
1362
1363 let (mut input, mut errs) = input.into_parts();
1364 input.reset(&start);
1365 if let Some(err) = err {
1366 errs.push(err);
1367 }
1368
1369 (input, o, errs)
1370 }
1371}
1372
1373#[cfg(test)]
1374mod tests {
1375 use super::*;
1376
1377 use snapbox::prelude::*;
1378 use snapbox::str;
1379
1380 use crate::binary::be_u16;
1381 use crate::error::ErrMode;
1382 use crate::error::Needed;
1383 use crate::error::TestResult;
1384 use crate::token::take;
1385 use crate::Partial;
1386
1387 #[doc(hidden)]
1388 #[macro_export]
1389 macro_rules! assert_size (
1390 ($t:ty, $sz:expr) => (
1391 assert!($crate::lib::std::mem::size_of::<$t>() <= $sz, "{} <= {} failed", $crate::lib::std::mem::size_of::<$t>(), $sz);
1392 );
1393 );
1394
1395 #[test]
1396 #[cfg(target_pointer_width = "64")]
1397 fn size_test() {
1398 assert_size!(Result<&[u8], (&[u8], u32)>, 40);
1399 assert_size!(Result<&str, u32>, 40);
1400 assert_size!(Needed, 8);
1401 assert_size!(ErrMode<u32>, 16);
1402 }
1403
1404 #[test]
1405 fn err_map_test() {
1406 let e = ErrMode::Backtrack(1);
1407 assert_eq!(e.map(|v| v + 1), ErrMode::Backtrack(2));
1408 }
1409
1410 #[test]
1411 fn single_element_tuples() {
1412 use crate::ascii::alpha1;
1413
1414 let mut parser = (alpha1,);
1415 assert_parse!(
1416 parser.parse_peek("abc123def"),
1417 str![[r#"
1418Ok(
1419 (
1420 "123def",
1421 (
1422 "abc",
1423 ),
1424 ),
1425)
1426
1427"#]]
1428 .raw()
1429 );
1430 assert_parse!(
1431 parser.parse_peek("123def"),
1432 str![[r#"
1433Err(
1434 Backtrack(
1435 InputError {
1436 input: "123def",
1437 },
1438 ),
1439)
1440
1441"#]]
1442 .raw()
1443 );
1444 }
1445
1446 #[test]
1447 fn tuple_test() {
1448 #[allow(clippy::type_complexity)]
1449 fn tuple_3<'i>(
1450 i: &mut Partial<&'i [u8]>,
1451 ) -> TestResult<Partial<&'i [u8]>, (u16, &'i [u8], &'i [u8])> {
1452 (be_u16, take(3u8), "fg").parse_next(i)
1453 }
1454
1455 assert_parse!(
1456 tuple_3.parse_peek(Partial::new(&b"abcdefgh"[..])),
1457 str![[r#"
1458Ok(
1459 (
1460 Partial {
1461 input: [
1462 104,
1463 ],
1464 partial: true,
1465 },
1466 (
1467 24930,
1468 [
1469 99,
1470 100,
1471 101,
1472 ],
1473 [
1474 102,
1475 103,
1476 ],
1477 ),
1478 ),
1479)
1480
1481"#]]
1482 .raw()
1483 );
1484 assert_parse!(
1485 tuple_3.parse_peek(Partial::new(&b"abcd"[..])),
1486 str![[r#"
1487Err(
1488 Incomplete(
1489 Size(
1490 1,
1491 ),
1492 ),
1493)
1494
1495"#]]
1496 .raw()
1497 );
1498 assert_parse!(
1499 tuple_3.parse_peek(Partial::new(&b"abcde"[..])),
1500 str![[r#"
1501Err(
1502 Incomplete(
1503 Unknown,
1504 ),
1505)
1506
1507"#]]
1508 .raw()
1509 );
1510 assert_parse!(
1511 tuple_3.parse_peek(Partial::new(&b"abcdejk"[..])),
1512 str![[r#"
1513Err(
1514 Backtrack(
1515 InputError {
1516 input: Partial {
1517 input: [
1518 106,
1519 107,
1520 ],
1521 partial: true,
1522 },
1523 },
1524 ),
1525)
1526
1527"#]]
1528 .raw()
1529 );
1530 }
1531
1532 #[test]
1533 fn unit_type() {
1534 fn parser<'i>(i: &mut &'i str) -> TestResult<&'i str, ()> {
1535 ().parse_next(i)
1536 }
1537 assert_parse!(
1538 parser.parse_peek("abxsbsh"),
1539 str![[r#"
1540Ok(
1541 (
1542 "abxsbsh",
1543 (),
1544 ),
1545)
1546
1547"#]]
1548 .raw()
1549 );
1550 assert_parse!(
1551 parser.parse_peek("sdfjakdsas"),
1552 str![[r#"
1553Ok(
1554 (
1555 "sdfjakdsas",
1556 (),
1557 ),
1558)
1559
1560"#]]
1561 .raw()
1562 );
1563 assert_parse!(
1564 parser.parse_peek(""),
1565 str![[r#"
1566Ok(
1567 (
1568 "",
1569 (),
1570 ),
1571)
1572
1573"#]]
1574 .raw()
1575 );
1576 }
1577}