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