winnow/
parser.rs

1//! Basic types to build the parsers
2
3use crate::ascii::Caseless as AsciiCaseless;
4use crate::combinator::*;
5#[cfg(feature = "unstable-recover")]
6#[cfg(feature = "std")]
7use crate::error::FromRecoverableError;
8use crate::error::{AddContext, FromExternalError, IResult, PResult, ParseError, ParserError};
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) -> PResult<()> {
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) -> PResult<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>>
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    {
59        debug_assert!(
60            !I::is_partial_supported(),
61            "partial streams need to handle `ErrMode::Incomplete`"
62        );
63
64        let start = input.checkpoint();
65        let (o, _) = (self.by_ref(), crate::combinator::eof)
66            .parse_next(&mut input)
67            .map_err(|e| {
68                let e = e
69                    .into_inner()
70                    .expect("complete parsers should not report `ErrMode::Incomplete(_)`");
71                ParseError::new(input, start, e)
72            })?;
73        Ok(o)
74    }
75
76    /// Take tokens from the [`Stream`], turning it into the output
77    ///
78    /// This includes advancing the [`Stream`] to the next location.
79    ///
80    /// On error, `input` will be left pointing at the error location.
81    fn parse_next(&mut self, input: &mut I) -> PResult<O, E>;
82
83    /// Take tokens from the [`Stream`], turning it into the output
84    ///
85    /// This includes advancing the [`Stream`] to the next location.
86    #[inline(always)]
87    fn parse_peek(&mut self, mut input: I) -> IResult<I, O, E> {
88        match self.parse_next(&mut input) {
89            Ok(o) => Ok((input, o)),
90            Err(err) => Err(err),
91        }
92    }
93
94    /// Treat `&mut Self` as a parser
95    ///
96    /// This helps when needing to move a `Parser` when all you have is a `&mut Parser`.
97    ///
98    /// # Example
99    ///
100    /// Because parsers are `FnMut`, they can be called multiple times. This prevents moving `f`
101    /// into [`length_take`][crate::binary::length_take] and `g` into
102    /// [`Parser::complete_err`]:
103    /// ```rust,compile_fail
104    /// # use winnow::prelude::*;
105    /// # use winnow::Parser;
106    /// # use winnow::error::ParserError;
107    /// # use winnow::binary::length_take;
108    /// pub fn length_value<'i, O, E: ParserError<&'i [u8]>>(
109    ///     mut f: impl Parser<&'i [u8], usize, E>,
110    ///     mut g: impl Parser<&'i [u8], O, E>
111    /// ) -> impl Parser<&'i [u8], O, E> {
112    ///   move |i: &mut &'i [u8]| {
113    ///     let mut data = length_take(f).parse_next(i)?;
114    ///     let o = g.complete_err().parse_next(&mut data)?;
115    ///     Ok(o)
116    ///   }
117    /// }
118    /// ```
119    ///
120    /// By adding `by_ref`, we can make this work:
121    /// ```rust
122    /// # use winnow::prelude::*;
123    /// # use winnow::Parser;
124    /// # use winnow::error::ParserError;
125    /// # use winnow::binary::length_take;
126    /// pub fn length_value<'i, O, E: ParserError<&'i [u8]>>(
127    ///     mut f: impl Parser<&'i [u8], usize, E>,
128    ///     mut g: impl Parser<&'i [u8], O, E>
129    /// ) -> impl Parser<&'i [u8], O, E> {
130    ///   move |i: &mut &'i [u8]| {
131    ///     let mut data = length_take(f.by_ref()).parse_next(i)?;
132    ///     let o = g.by_ref().complete_err().parse_next(&mut data)?;
133    ///     Ok(o)
134    ///   }
135    /// }
136    /// ```
137    #[inline(always)]
138    fn by_ref(&mut self) -> ByRef<'_, Self>
139    where
140        Self: core::marker::Sized,
141    {
142        ByRef::new(self)
143    }
144
145    /// Produce the provided value
146    ///
147    /// # Example
148    ///
149    /// ```rust
150    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
151    /// use winnow::ascii::alpha1;
152    /// # fn main() {
153    ///
154    /// let mut parser = alpha1.value(1234);
155    ///
156    /// assert_eq!(parser.parse_peek("abcd"), Ok(("", 1234)));
157    /// assert_eq!(parser.parse_peek("123abcd;"), Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice))));
158    /// # }
159    /// ```
160    #[doc(alias = "to")]
161    #[inline(always)]
162    fn value<O2>(self, val: O2) -> Value<Self, I, O, O2, E>
163    where
164        Self: core::marker::Sized,
165        O2: Clone,
166    {
167        Value::new(self, val)
168    }
169
170    /// Produce a type's default value
171    ///
172    /// # Example
173    ///
174    /// ```rust
175    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
176    /// use winnow::ascii::alpha1;
177    /// # fn main() {
178    ///
179    /// let mut parser = alpha1.default_value::<u32>();
180    ///
181    /// assert_eq!(parser.parse_peek("abcd"), Ok(("", 0)));
182    /// assert_eq!(parser.parse_peek("123abcd;"), Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice))));
183    /// # }
184    /// ```
185    #[inline(always)]
186    fn default_value<O2>(self) -> DefaultValue<Self, I, O, O2, E>
187    where
188        Self: core::marker::Sized,
189        O2: core::default::Default,
190    {
191        DefaultValue::new(self)
192    }
193
194    /// Discards the output of the `Parser`
195    ///
196    /// # Example
197    ///
198    /// ```rust
199    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
200    /// use winnow::ascii::alpha1;
201    /// # fn main() {
202    ///
203    /// let mut parser = alpha1.void();
204    ///
205    /// assert_eq!(parser.parse_peek("abcd"), Ok(("", ())));
206    /// assert_eq!(parser.parse_peek("123abcd;"), Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice))));
207    /// # }
208    /// ```
209    #[inline(always)]
210    fn void(self) -> Void<Self, I, O, E>
211    where
212        Self: core::marker::Sized,
213    {
214        Void::new(self)
215    }
216
217    /// Convert the parser's output to another type using [`std::convert::From`]
218    ///
219    /// # Example
220    ///
221    /// ```rust
222    /// # use winnow::prelude::*;
223    /// # use winnow::error::InputError;
224    /// use winnow::ascii::alpha1;
225    /// # fn main() {
226    ///
227    /// fn parser1<'s>(i: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
228    ///   alpha1(i)
229    /// }
230    ///
231    /// let mut parser2 = parser1.output_into();
232    ///
233    /// // the parser converts the &str output of the child parser into a Vec<u8>
234    /// let bytes: IResult<&str, Vec<u8>> = parser2.parse_peek("abcd");
235    /// assert_eq!(bytes, Ok(("", vec![97, 98, 99, 100])));
236    /// # }
237    /// ```
238    #[inline(always)]
239    fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E>
240    where
241        Self: core::marker::Sized,
242        O: Into<O2>,
243    {
244        OutputInto::new(self)
245    }
246
247    /// Produce the consumed input as produced value.
248    ///
249    /// # Example
250    ///
251    /// ```rust
252    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
253    /// use winnow::ascii::{alpha1};
254    /// use winnow::combinator::separated_pair;
255    /// # fn main() {
256    ///
257    /// let mut parser = separated_pair(alpha1, ',', alpha1).take();
258    ///
259    /// assert_eq!(parser.parse_peek("abcd,efgh"), Ok(("", "abcd,efgh")));
260    /// assert_eq!(parser.parse_peek("abcd;"),Err(ErrMode::Backtrack(InputError::new(";", ErrorKind::Tag))));
261    /// # }
262    /// ```
263    #[doc(alias = "concat")]
264    #[doc(alias = "recognize")]
265    #[inline(always)]
266    fn take(self) -> Take<Self, I, O, E>
267    where
268        Self: core::marker::Sized,
269        I: Stream,
270    {
271        Take::new(self)
272    }
273
274    /// Replaced with [`Parser::take`]
275    #[inline(always)]
276    #[deprecated(since = "0.6.14", note = "Replaced with `Parser::take`")]
277    fn recognize(self) -> Take<Self, I, O, E>
278    where
279        Self: core::marker::Sized,
280        I: Stream,
281    {
282        Take::new(self)
283    }
284
285    /// Produce the consumed input with the output
286    ///
287    /// Functions similarly to [take][Parser::take] except it
288    /// returns the parser output as well.
289    ///
290    /// This can be useful especially in cases where the output is not the same type
291    /// as the input, or the input is a user defined type.
292    ///
293    /// Returned tuple is of the format `(produced output, consumed input)`.
294    ///
295    /// # Example
296    ///
297    /// ```rust
298    /// # use winnow::prelude::*;
299    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError};
300    /// use winnow::ascii::{alpha1};
301    /// use winnow::token::literal;
302    /// use winnow::combinator::separated_pair;
303    ///
304    /// fn inner_parser<'s>(input: &mut &'s str) -> PResult<bool, InputError<&'s str>> {
305    ///     "1234".value(true).parse_next(input)
306    /// }
307    ///
308    /// let mut consumed_parser = separated_pair(alpha1, ',', alpha1).value(true).with_taken();
309    ///
310    /// assert_eq!(consumed_parser.parse_peek("abcd,efgh1"), Ok(("1", (true, "abcd,efgh"))));
311    /// assert_eq!(consumed_parser.parse_peek("abcd;"),Err(ErrMode::Backtrack(InputError::new(";", ErrorKind::Tag))));
312    ///
313    /// // the second output (representing the consumed input)
314    /// // should be the same as that of the `take` parser.
315    /// let mut take_parser = inner_parser.take();
316    /// let mut consumed_parser = inner_parser.with_taken().map(|(output, consumed)| consumed);
317    ///
318    /// assert_eq!(take_parser.parse_peek("1234"), consumed_parser.parse_peek("1234"));
319    /// assert_eq!(take_parser.parse_peek("abcd"), consumed_parser.parse_peek("abcd"));
320    /// ```
321    #[doc(alias = "consumed")]
322    #[doc(alias = "with_recognized")]
323    #[inline(always)]
324    fn with_taken(self) -> WithTaken<Self, I, O, E>
325    where
326        Self: core::marker::Sized,
327        I: Stream,
328    {
329        WithTaken::new(self)
330    }
331
332    /// Replaced with [`Parser::with_taken`]
333    #[inline(always)]
334    #[deprecated(since = "0.6.14", note = "Replaced with `Parser::with_taken`")]
335    fn with_recognized(self) -> WithTaken<Self, I, O, E>
336    where
337        Self: core::marker::Sized,
338        I: Stream,
339    {
340        WithTaken::new(self)
341    }
342
343    /// Produce the location of the consumed input as produced value.
344    ///
345    /// # Example
346    ///
347    /// ```rust
348    /// # use winnow::prelude::*;
349    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, stream::Stream};
350    /// use winnow::stream::Located;
351    /// use winnow::ascii::alpha1;
352    /// use winnow::combinator::separated_pair;
353    ///
354    /// let mut parser = separated_pair(alpha1.span(), ',', alpha1.span());
355    ///
356    /// assert_eq!(parser.parse(Located::new("abcd,efgh")), Ok((0..4, 5..9)));
357    /// assert_eq!(parser.parse_peek(Located::new("abcd;")),Err(ErrMode::Backtrack(InputError::new(Located::new("abcd;").peek_slice(4).0, ErrorKind::Tag))));
358    /// ```
359    #[inline(always)]
360    fn span(self) -> Span<Self, I, O, E>
361    where
362        Self: core::marker::Sized,
363        I: Stream + Location,
364    {
365        Span::new(self)
366    }
367
368    /// Produce the location of consumed input with the output
369    ///
370    /// Functions similarly to [`Parser::span`] except it
371    /// returns the parser output as well.
372    ///
373    /// This can be useful especially in cases where the output is not the same type
374    /// as the input, or the input is a user defined type.
375    ///
376    /// Returned tuple is of the format `(produced output, consumed input)`.
377    ///
378    /// # Example
379    ///
380    /// ```rust
381    /// # use winnow::prelude::*;
382    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, stream::Stream};
383    /// use winnow::stream::Located;
384    /// use winnow::ascii::alpha1;
385    /// use winnow::token::literal;
386    /// use winnow::combinator::separated_pair;
387    ///
388    /// fn inner_parser<'s>(input: &mut Located<&'s str>) -> PResult<bool, InputError<Located<&'s str>>> {
389    ///     "1234".value(true).parse_next(input)
390    /// }
391    ///
392    /// # fn main() {
393    ///
394    /// let mut consumed_parser = separated_pair(alpha1.value(1).with_span(), ',', alpha1.value(2).with_span());
395    ///
396    /// assert_eq!(consumed_parser.parse(Located::new("abcd,efgh")), Ok(((1, 0..4), (2, 5..9))));
397    /// assert_eq!(consumed_parser.parse_peek(Located::new("abcd;")),Err(ErrMode::Backtrack(InputError::new(Located::new("abcd;").peek_slice(4).0, ErrorKind::Tag))));
398    ///
399    /// // the second output (representing the consumed input)
400    /// // should be the same as that of the `span` parser.
401    /// let mut span_parser = inner_parser.span();
402    /// let mut consumed_parser = inner_parser.with_span().map(|(output, consumed)| consumed);
403    ///
404    /// assert_eq!(span_parser.parse_peek(Located::new("1234")), consumed_parser.parse_peek(Located::new("1234")));
405    /// assert_eq!(span_parser.parse_peek(Located::new("abcd")), consumed_parser.parse_peek(Located::new("abcd")));
406    /// # }
407    /// ```
408    #[inline(always)]
409    fn with_span(self) -> WithSpan<Self, I, O, E>
410    where
411        Self: core::marker::Sized,
412        I: Stream + Location,
413    {
414        WithSpan::new(self)
415    }
416
417    /// Maps a function over the output of a parser
418    ///
419    /// # Example
420    ///
421    /// ```rust
422    /// use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
423    /// use winnow::ascii::digit1;
424    /// # fn main() {
425    ///
426    /// let mut parser = digit1.map(|s: &str| s.len());
427    ///
428    /// // the parser will count how many characters were returned by digit1
429    /// assert_eq!(parser.parse_peek("123456"), Ok(("", 6)));
430    ///
431    /// // this will fail if digit1 fails
432    /// assert_eq!(parser.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice))));
433    /// # }
434    /// ```
435    #[inline(always)]
436    fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E>
437    where
438        G: FnMut(O) -> O2,
439        Self: core::marker::Sized,
440    {
441        Map::new(self, map)
442    }
443
444    /// Applies a function returning a `Result` over the output of a parser.
445    ///
446    /// # Example
447    ///
448    /// ```rust
449    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
450    /// use winnow::ascii::digit1;
451    /// # fn main() {
452    ///
453    /// let mut parse = digit1.try_map(|s: &str| s.parse::<u8>());
454    ///
455    /// // the parser will convert the result of digit1 to a number
456    /// assert_eq!(parse.parse_peek("123"), Ok(("", 123)));
457    ///
458    /// // this will fail if digit1 fails
459    /// assert_eq!(parse.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice))));
460    ///
461    /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
462    /// assert_eq!(parse.parse_peek("123456"), Err(ErrMode::Backtrack(InputError::new("123456", ErrorKind::Verify))));
463    /// # }
464    /// ```
465    #[inline(always)]
466    fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2>
467    where
468        Self: core::marker::Sized,
469        G: FnMut(O) -> Result<O2, E2>,
470        I: Stream,
471        E: FromExternalError<I, E2>,
472    {
473        TryMap::new(self, map)
474    }
475
476    /// Apply both [`Parser::verify`] and [`Parser::map`].
477    ///
478    /// # Example
479    ///
480    /// ```rust
481    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
482    /// use winnow::ascii::digit1;
483    /// # fn main() {
484    ///
485    /// let mut parse = digit1.verify_map(|s: &str| s.parse::<u8>().ok());
486    ///
487    /// // the parser will convert the result of digit1 to a number
488    /// assert_eq!(parse.parse_peek("123"), Ok(("", 123)));
489    ///
490    /// // this will fail if digit1 fails
491    /// assert_eq!(parse.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice))));
492    ///
493    /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
494    /// assert_eq!(parse.parse_peek("123456"), Err(ErrMode::Backtrack(InputError::new("123456", ErrorKind::Verify))));
495    /// # }
496    /// ```
497    #[doc(alias = "satisfy_map")]
498    #[doc(alias = "filter_map")]
499    #[doc(alias = "map_opt")]
500    #[inline(always)]
501    fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E>
502    where
503        Self: core::marker::Sized,
504        G: FnMut(O) -> Option<O2>,
505        I: Stream,
506        E: ParserError<I>,
507    {
508        VerifyMap::new(self, map)
509    }
510
511    /// Creates a parser from the output of this one
512    ///
513    /// # Example
514    ///
515    /// ```rust
516    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, PResult, Parser};
517    /// use winnow::token::take;
518    /// use winnow::binary::u8;
519    ///
520    /// fn length_take<'s>(input: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
521    ///     u8.flat_map(take).parse_next(input)
522    /// }
523    ///
524    /// assert_eq!(length_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
525    /// assert_eq!(length_take.parse_peek(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(InputError::new(&[0, 1, 2][..], ErrorKind::Slice))));
526    /// ```
527    ///
528    /// which is the same as
529    /// ```rust
530    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, PResult, Parser};
531    /// use winnow::token::take;
532    /// use winnow::binary::u8;
533    ///
534    /// fn length_take<'s>(input: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
535    ///     let length = u8.parse_next(input)?;
536    ///     let data = take(length).parse_next(input)?;
537    ///     Ok(data)
538    /// }
539    ///
540    /// assert_eq!(length_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
541    /// assert_eq!(length_take.parse_peek(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(InputError::new(&[0, 1, 2][..], ErrorKind::Slice))));
542    /// ```
543    #[inline(always)]
544    fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E>
545    where
546        Self: core::marker::Sized,
547        G: FnMut(O) -> H,
548        H: Parser<I, O2, E>,
549    {
550        FlatMap::new(self, map)
551    }
552
553    /// Applies a second parser over the output of the first one
554    ///
555    /// # Example
556    ///
557    /// ```rust
558    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
559    /// use winnow::ascii::digit1;
560    /// use winnow::token::take;
561    /// # fn main() {
562    ///
563    /// let mut digits = take(5u8).and_then(digit1);
564    ///
565    /// assert_eq!(digits.parse_peek("12345"), Ok(("", "12345")));
566    /// assert_eq!(digits.parse_peek("123ab"), Ok(("", "123")));
567    /// assert_eq!(digits.parse_peek("123"), Err(ErrMode::Backtrack(InputError::new("123", ErrorKind::Slice))));
568    /// # }
569    /// ```
570    #[inline(always)]
571    fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E>
572    where
573        Self: core::marker::Sized,
574        G: Parser<O, O2, E>,
575        O: StreamIsPartial,
576        I: Stream,
577    {
578        AndThen::new(self, inner)
579    }
580
581    /// Apply [`std::str::FromStr`] to the output of the parser
582    ///
583    /// # Example
584    ///
585    /// ```rust
586    /// # use winnow::prelude::*;
587    /// use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
588    /// use winnow::ascii::digit1;
589    ///
590    /// fn parser<'s>(input: &mut &'s str) -> PResult<u64, InputError<&'s str>> {
591    ///     digit1.parse_to().parse_next(input)
592    /// }
593    ///
594    /// // the parser will count how many characters were returned by digit1
595    /// assert_eq!(parser.parse_peek("123456"), Ok(("", 123456)));
596    ///
597    /// // this will fail if digit1 fails
598    /// assert_eq!(parser.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Slice))));
599    /// ```
600    #[doc(alias = "from_str")]
601    #[inline(always)]
602    fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E>
603    where
604        Self: core::marker::Sized,
605        I: Stream,
606        O: ParseSlice<O2>,
607        E: ParserError<I>,
608    {
609        ParseTo::new(self)
610    }
611
612    /// Returns the output of the child parser if it satisfies a verification function.
613    ///
614    /// The verification function takes as argument a reference to the output of the
615    /// parser.
616    ///
617    /// # Example
618    ///
619    /// ```rust
620    /// # use winnow::{error::ErrMode,error::ErrorKind, error::InputError, Parser};
621    /// # use winnow::ascii::alpha1;
622    /// # fn main() {
623    ///
624    /// let mut parser = alpha1.verify(|s: &str| s.len() == 4);
625    ///
626    /// assert_eq!(parser.parse_peek("abcd"), Ok(("", "abcd")));
627    /// assert_eq!(parser.parse_peek("abcde"), Err(ErrMode::Backtrack(InputError::new("abcde", ErrorKind::Verify))));
628    /// assert_eq!(parser.parse_peek("123abcd;"),Err(ErrMode::Backtrack(InputError::new("123abcd;", ErrorKind::Slice))));
629    /// # }
630    /// ```
631    #[doc(alias = "satisfy")]
632    #[doc(alias = "filter")]
633    #[inline(always)]
634    fn verify<G, O2>(self, filter: G) -> Verify<Self, G, I, O, O2, E>
635    where
636        Self: core::marker::Sized,
637        G: FnMut(&O2) -> bool,
638        I: Stream,
639        O: crate::lib::std::borrow::Borrow<O2>,
640        O2: ?Sized,
641        E: ParserError<I>,
642    {
643        Verify::new(self, filter)
644    }
645
646    /// If parsing fails, add context to the error
647    ///
648    /// This is used mainly to add user friendly information
649    /// to errors when backtracking through a parse tree.
650    #[doc(alias = "labelled")]
651    #[inline(always)]
652    fn context<C>(self, context: C) -> Context<Self, I, O, E, C>
653    where
654        Self: core::marker::Sized,
655        I: Stream,
656        E: AddContext<I, C>,
657        C: Clone + crate::lib::std::fmt::Debug,
658    {
659        Context::new(self, context)
660    }
661
662    /// Transforms [`Incomplete`][crate::error::ErrMode::Incomplete] into [`Backtrack`][crate::error::ErrMode::Backtrack]
663    ///
664    /// # Example
665    ///
666    /// ```rust
667    /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, stream::Partial, Parser};
668    /// # use winnow::token::take;
669    /// # fn main() {
670    ///
671    /// let mut parser = take(5u8).complete_err();
672    ///
673    /// assert_eq!(parser.parse_peek(Partial::new("abcdefg")), Ok((Partial::new("fg"), "abcde")));
674    /// assert_eq!(parser.parse_peek(Partial::new("abcd")), Err(ErrMode::Backtrack(InputError::new(Partial::new("abcd"), ErrorKind::Complete))));
675    /// # }
676    /// ```
677    #[inline(always)]
678    fn complete_err(self) -> CompleteErr<Self>
679    where
680        Self: core::marker::Sized,
681    {
682        CompleteErr::new(self)
683    }
684
685    /// Convert the parser's error to another type using [`std::convert::From`]
686    #[inline(always)]
687    fn err_into<E2>(self) -> ErrInto<Self, I, O, E, E2>
688    where
689        Self: core::marker::Sized,
690        E: Into<E2>,
691    {
692        ErrInto::new(self)
693    }
694
695    /// Recover from an error by skipping everything `recover` consumes and trying again
696    ///
697    /// If `recover` consumes nothing, the error is returned, allowing an alternative recovery
698    /// method.
699    ///
700    /// This commits the parse result, preventing alternative branch paths like with
701    /// [`winnow::combinator::alt`][crate::combinator::alt].
702    #[inline(always)]
703    #[cfg(feature = "unstable-recover")]
704    #[cfg(feature = "std")]
705    fn retry_after<R>(self, recover: R) -> RetryAfter<Self, R, I, O, E>
706    where
707        Self: core::marker::Sized,
708        R: Parser<I, (), E>,
709        I: Stream,
710        I: Recover<E>,
711        E: FromRecoverableError<I, E>,
712    {
713        RetryAfter::new(self, recover)
714    }
715
716    /// Recover from an error by skipping this parse and everything `recover` consumes
717    ///
718    /// This commits the parse result, preventing alternative branch paths like with
719    /// [`winnow::combinator::alt`][crate::combinator::alt].
720    #[inline(always)]
721    #[cfg(feature = "unstable-recover")]
722    #[cfg(feature = "std")]
723    fn resume_after<R>(self, recover: R) -> ResumeAfter<Self, R, I, O, E>
724    where
725        Self: core::marker::Sized,
726        R: Parser<I, (), E>,
727        I: Stream,
728        I: Recover<E>,
729        E: FromRecoverableError<I, E>,
730    {
731        ResumeAfter::new(self, recover)
732    }
733}
734
735impl<'a, I, O, E, F> Parser<I, O, E> for F
736where
737    F: FnMut(&mut I) -> PResult<O, E> + 'a,
738    I: Stream,
739{
740    #[inline(always)]
741    fn parse_next(&mut self, i: &mut I) -> PResult<O, E> {
742        self(i)
743    }
744}
745
746/// This is a shortcut for [`one_of`][crate::token::one_of].
747///
748/// # Example
749///
750/// ```
751/// # use winnow::prelude::*;
752/// # use winnow::{error::ErrMode, error::{ErrorKind, InputError}};
753/// fn parser<'s>(i: &mut &'s [u8]) -> PResult<u8, InputError<&'s [u8]>>  {
754///     b'a'.parse_next(i)
755/// }
756/// assert_eq!(parser.parse_peek(&b"abc"[..]), Ok((&b"bc"[..], b'a')));
757/// assert_eq!(parser.parse_peek(&b" abc"[..]), Err(ErrMode::Backtrack(InputError::new(&b" abc"[..], ErrorKind::Tag))));
758/// assert_eq!(parser.parse_peek(&b"bc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"bc"[..], ErrorKind::Tag))));
759/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Tag))));
760/// ```
761impl<I, E> Parser<I, u8, E> for u8
762where
763    I: StreamIsPartial,
764    I: Stream,
765    I: Compare<u8>,
766    E: ParserError<I>,
767{
768    #[inline(always)]
769    fn parse_next(&mut self, i: &mut I) -> PResult<u8, E> {
770        crate::token::literal(*self).value(*self).parse_next(i)
771    }
772}
773
774/// This is a shortcut for [`one_of`][crate::token::one_of].
775///
776/// # Example
777///
778/// ```
779/// # use winnow::prelude::*;
780/// # use winnow::{error::ErrMode, error::{ErrorKind, InputError}};
781/// fn parser<'s>(i: &mut &'s str) -> PResult<char, InputError<&'s str>> {
782///     'a'.parse_next(i)
783/// }
784/// assert_eq!(parser.parse_peek("abc"), Ok(("bc", 'a')));
785/// assert_eq!(parser.parse_peek(" abc"), Err(ErrMode::Backtrack(InputError::new(" abc", ErrorKind::Tag))));
786/// assert_eq!(parser.parse_peek("bc"), Err(ErrMode::Backtrack(InputError::new("bc", ErrorKind::Tag))));
787/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
788/// ```
789impl<I, E> Parser<I, char, E> for char
790where
791    I: StreamIsPartial,
792    I: Stream,
793    I: Compare<char>,
794    E: ParserError<I>,
795{
796    #[inline(always)]
797    fn parse_next(&mut self, i: &mut I) -> PResult<char, E> {
798        crate::token::literal(*self).value(*self).parse_next(i)
799    }
800}
801
802/// This is a shortcut for [`literal`][crate::token::literal].
803///
804/// # Example
805/// ```rust
806/// # use winnow::prelude::*;
807/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
808/// # use winnow::combinator::alt;
809/// # use winnow::token::take;
810///
811/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
812///   alt((&"Hello"[..], take(5usize))).parse_next(s)
813/// }
814///
815/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
816/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
817/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
818/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
819/// ```
820impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8]
821where
822    I: Compare<&'s [u8]> + StreamIsPartial,
823    I: Stream,
824{
825    #[inline(always)]
826    fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
827        crate::token::literal(*self).parse_next(i)
828    }
829}
830
831/// This is a shortcut for [`literal`][crate::token::literal].
832///
833/// # Example
834/// ```rust
835/// # use winnow::prelude::*;
836/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
837/// # use winnow::combinator::alt;
838/// # use winnow::token::take;
839/// use winnow::ascii::Caseless;
840///
841/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
842///   alt((Caseless(&"hello"[..]), take(5usize))).parse_next(s)
843/// }
844///
845/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
846/// assert_eq!(parser.parse_peek(&b"hello, World!"[..]), Ok((&b", World!"[..], &b"hello"[..])));
847/// assert_eq!(parser.parse_peek(&b"HeLlo, World!"[..]), Ok((&b", World!"[..], &b"HeLlo"[..])));
848/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
849/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
850/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
851/// ```
852impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s [u8]>
853where
854    I: Compare<AsciiCaseless<&'s [u8]>> + StreamIsPartial,
855    I: Stream,
856{
857    #[inline(always)]
858    fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
859        crate::token::literal(*self).parse_next(i)
860    }
861}
862
863/// This is a shortcut for [`literal`][crate::token::literal].
864///
865/// # Example
866/// ```rust
867/// # use winnow::prelude::*;
868/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
869/// # use winnow::combinator::alt;
870/// # use winnow::token::take;
871///
872/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
873///   alt((b"Hello", take(5usize))).parse_next(s)
874/// }
875///
876/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
877/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
878/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
879/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
880/// ```
881impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N]
882where
883    I: Compare<&'s [u8; N]> + StreamIsPartial,
884    I: Stream,
885{
886    #[inline(always)]
887    fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
888        crate::token::literal(*self).parse_next(i)
889    }
890}
891
892/// This is a shortcut for [`literal`][crate::token::literal].
893///
894/// # Example
895/// ```rust
896/// # use winnow::prelude::*;
897/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
898/// # use winnow::combinator::alt;
899/// # use winnow::token::take;
900/// use winnow::ascii::Caseless;
901///
902/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
903///   alt((Caseless(b"hello"), take(5usize))).parse_next(s)
904/// }
905///
906/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
907/// assert_eq!(parser.parse_peek(&b"hello, World!"[..]), Ok((&b", World!"[..], &b"hello"[..])));
908/// assert_eq!(parser.parse_peek(&b"HeLlo, World!"[..]), Ok((&b", World!"[..], &b"HeLlo"[..])));
909/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
910/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
911/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
912/// ```
913impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E>
914    for AsciiCaseless<&'s [u8; N]>
915where
916    I: Compare<AsciiCaseless<&'s [u8; N]>> + StreamIsPartial,
917    I: Stream,
918{
919    #[inline(always)]
920    fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
921        crate::token::literal(*self).parse_next(i)
922    }
923}
924
925/// This is a shortcut for [`literal`][crate::token::literal].
926///
927/// # Example
928/// ```rust
929/// # use winnow::prelude::*;
930/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}};
931/// # use winnow::combinator::alt;
932/// # use winnow::token::take;
933///
934/// fn parser<'s>(s: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
935///   alt(("Hello", take(5usize))).parse_next(s)
936/// }
937///
938/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello")));
939/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet")));
940/// assert_eq!(parser.parse_peek("Some"), Err(ErrMode::Backtrack(InputError::new("Some", ErrorKind::Slice))));
941/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Slice))));
942/// ```
943impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str
944where
945    I: Compare<&'s str> + StreamIsPartial,
946    I: Stream,
947{
948    #[inline(always)]
949    fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
950        crate::token::literal(*self).parse_next(i)
951    }
952}
953
954/// This is a shortcut for [`literal`][crate::token::literal].
955///
956/// # Example
957/// ```rust
958/// # use winnow::prelude::*;
959/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}};
960/// # use winnow::combinator::alt;
961/// # use winnow::token::take;
962/// # use winnow::ascii::Caseless;
963///
964/// fn parser<'s>(s: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
965///   alt((Caseless("hello"), take(5usize))).parse_next(s)
966/// }
967///
968/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello")));
969/// assert_eq!(parser.parse_peek("hello, World!"), Ok((", World!", "hello")));
970/// assert_eq!(parser.parse_peek("HeLlo, World!"), Ok((", World!", "HeLlo")));
971/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet")));
972/// assert_eq!(parser.parse_peek("Some"), Err(ErrMode::Backtrack(InputError::new("Some", ErrorKind::Slice))));
973/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Slice))));
974/// ```
975impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s str>
976where
977    I: Compare<AsciiCaseless<&'s str>> + StreamIsPartial,
978    I: Stream,
979{
980    #[inline(always)]
981    fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
982        crate::token::literal(*self).parse_next(i)
983    }
984}
985
986impl<I: Stream, E: ParserError<I>> Parser<I, (), E> for () {
987    #[inline(always)]
988    fn parse_next(&mut self, _i: &mut I) -> PResult<(), E> {
989        Ok(())
990    }
991}
992
993macro_rules! impl_parser_for_tuple {
994  ($($parser:ident $output:ident),+) => (
995    #[allow(non_snake_case)]
996    impl<I: Stream, $($output),+, E: ParserError<I>, $($parser),+> Parser<I, ($($output),+,), E> for ($($parser),+,)
997    where
998      $($parser: Parser<I, $output, E>),+
999    {
1000      #[inline(always)]
1001      fn parse_next(&mut self, i: &mut I) -> PResult<($($output),+,), E> {
1002        let ($(ref mut $parser),+,) = *self;
1003
1004        $(let $output = $parser.parse_next(i)?;)+
1005
1006        Ok(($($output),+,))
1007      }
1008    }
1009  )
1010}
1011
1012macro_rules! impl_parser_for_tuples {
1013    ($parser1:ident $output1:ident, $($parser:ident $output:ident),+) => {
1014        impl_parser_for_tuples!(__impl $parser1 $output1; $($parser $output),+);
1015    };
1016    (__impl $($parser:ident $output:ident),+; $parser1:ident $output1:ident $(,$parser2:ident $output2:ident)*) => {
1017        impl_parser_for_tuple!($($parser $output),+);
1018        impl_parser_for_tuples!(__impl $($parser $output),+, $parser1 $output1; $($parser2 $output2),*);
1019    };
1020    (__impl $($parser:ident $output:ident),+;) => {
1021        impl_parser_for_tuple!($($parser $output),+);
1022    }
1023}
1024
1025/// Collect all errors when parsing the input
1026///
1027/// [`Parser`]s will need to use [`Recoverable<I, _>`] for their input.
1028#[cfg(feature = "unstable-recover")]
1029#[cfg(feature = "std")]
1030pub trait RecoverableParser<I, O, R, E> {
1031    /// Collect all errors when parsing the input
1032    ///
1033    /// If `self` fails, this acts like [`Parser::resume_after`] and returns `Ok(None)`.
1034    /// Generally, this should be avoided by using
1035    /// [`Parser::retry_after`] and [`Parser::resume_after`] throughout your parser.
1036    ///
1037    /// The empty `input` is returned to allow turning the errors into [`ParserError`]s.
1038    fn recoverable_parse(&mut self, input: I) -> (I, Option<O>, Vec<R>);
1039}
1040
1041#[cfg(feature = "unstable-recover")]
1042#[cfg(feature = "std")]
1043impl<P, I, O, R, E> RecoverableParser<I, O, R, E> for P
1044where
1045    P: Parser<Recoverable<I, R>, O, E>,
1046    I: Stream,
1047    I: StreamIsPartial,
1048    R: FromRecoverableError<Recoverable<I, R>, E>,
1049    R: crate::lib::std::fmt::Debug,
1050    E: FromRecoverableError<Recoverable<I, R>, E>,
1051    E: ParserError<Recoverable<I, R>>,
1052    E: crate::lib::std::fmt::Debug,
1053{
1054    #[inline]
1055    fn recoverable_parse(&mut self, input: I) -> (I, Option<O>, Vec<R>) {
1056        debug_assert!(
1057            !I::is_partial_supported(),
1058            "partial streams need to handle `ErrMode::Incomplete`"
1059        );
1060
1061        let start = input.checkpoint();
1062        let mut input = Recoverable::new(input);
1063        let start_token = input.checkpoint();
1064        let result = (
1065            self.by_ref(),
1066            crate::combinator::eof.resume_after(rest.void()),
1067        )
1068            .parse_next(&mut input);
1069
1070        let (o, err) = match result {
1071            Ok((o, _)) => (Some(o), None),
1072            Err(err) => {
1073                let err = err
1074                    .into_inner()
1075                    .expect("complete parsers should not report `ErrMode::Incomplete(_)`");
1076                let err_start = input.checkpoint();
1077                let err = R::from_recoverable_error(&start_token, &err_start, &input, err);
1078                (None, Some(err))
1079            }
1080        };
1081
1082        let (mut input, mut errs) = input.into_parts();
1083        input.reset(&start);
1084        if let Some(err) = err {
1085            errs.push(err);
1086        }
1087
1088        (input, o, errs)
1089    }
1090}
1091
1092impl_parser_for_tuples!(
1093  P1 O1,
1094  P2 O2,
1095  P3 O3,
1096  P4 O4,
1097  P5 O5,
1098  P6 O6,
1099  P7 O7,
1100  P8 O8,
1101  P9 O9,
1102  P10 O10,
1103  P11 O11,
1104  P12 O12,
1105  P13 O13,
1106  P14 O14,
1107  P15 O15,
1108  P16 O16,
1109  P17 O17,
1110  P18 O18,
1111  P19 O19,
1112  P20 O20,
1113  P21 O21
1114);
1115
1116#[cfg(feature = "alloc")]
1117use crate::lib::std::boxed::Box;
1118
1119#[cfg(feature = "alloc")]
1120impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> {
1121    #[inline(always)]
1122    fn parse_next(&mut self, i: &mut I) -> PResult<O, E> {
1123        (**self).parse_next(i)
1124    }
1125}
1126
1127/// Convert a [`Parser::parse_peek`] style parse function to be a [`Parser`]
1128#[inline(always)]
1129pub fn unpeek<'a, I, O, E>(
1130    mut peek: impl FnMut(I) -> IResult<I, O, E> + 'a,
1131) -> impl FnMut(&mut I) -> PResult<O, E>
1132where
1133    I: Clone,
1134{
1135    move |input| match peek((*input).clone()) {
1136        Ok((i, o)) => {
1137            *input = i;
1138            Ok(o)
1139        }
1140        Err(err) => Err(err),
1141    }
1142}
1143
1144#[cfg(test)]
1145mod tests {
1146    use super::*;
1147    use crate::binary::be_u16;
1148    use crate::error::ErrMode;
1149    use crate::error::ErrorKind;
1150    use crate::error::InputError;
1151    use crate::error::Needed;
1152    use crate::token::take;
1153    use crate::Partial;
1154
1155    #[doc(hidden)]
1156    #[macro_export]
1157    macro_rules! assert_size (
1158    ($t:ty, $sz:expr) => (
1159      assert!($crate::lib::std::mem::size_of::<$t>() <= $sz, "{} <= {} failed", $crate::lib::std::mem::size_of::<$t>(), $sz);
1160    );
1161  );
1162
1163    #[test]
1164    #[cfg(target_pointer_width = "64")]
1165    fn size_test() {
1166        assert_size!(IResult<&[u8], &[u8], (&[u8], u32)>, 40);
1167        assert_size!(IResult<&str, &str, u32>, 40);
1168        assert_size!(Needed, 8);
1169        assert_size!(ErrMode<u32>, 16);
1170        assert_size!(ErrorKind, 1);
1171    }
1172
1173    #[test]
1174    fn err_map_test() {
1175        let e = ErrMode::Backtrack(1);
1176        assert_eq!(e.map(|v| v + 1), ErrMode::Backtrack(2));
1177    }
1178
1179    #[test]
1180    fn single_element_tuples() {
1181        use crate::ascii::alpha1;
1182        use crate::error::ErrorKind;
1183
1184        let mut parser = (alpha1,);
1185        assert_eq!(parser.parse_peek("abc123def"), Ok(("123def", ("abc",))));
1186        assert_eq!(
1187            parser.parse_peek("123def"),
1188            Err(ErrMode::Backtrack(InputError::new(
1189                "123def",
1190                ErrorKind::Slice
1191            )))
1192        );
1193    }
1194
1195    #[test]
1196    fn tuple_test() {
1197        #[allow(clippy::type_complexity)]
1198        fn tuple_3(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (u16, &[u8], &[u8])> {
1199            (be_u16, take(3u8), "fg").parse_peek(i)
1200        }
1201
1202        assert_eq!(
1203            tuple_3(Partial::new(&b"abcdefgh"[..])),
1204            Ok((
1205                Partial::new(&b"h"[..]),
1206                (0x6162u16, &b"cde"[..], &b"fg"[..])
1207            ))
1208        );
1209        assert_eq!(
1210            tuple_3(Partial::new(&b"abcd"[..])),
1211            Err(ErrMode::Incomplete(Needed::new(1)))
1212        );
1213        assert_eq!(
1214            tuple_3(Partial::new(&b"abcde"[..])),
1215            Err(ErrMode::Incomplete(Needed::new(2)))
1216        );
1217        assert_eq!(
1218            tuple_3(Partial::new(&b"abcdejk"[..])),
1219            Err(ErrMode::Backtrack(error_position!(
1220                &Partial::new(&b"jk"[..]),
1221                ErrorKind::Tag
1222            )))
1223        );
1224    }
1225
1226    #[test]
1227    fn unit_type() {
1228        fn parser(i: &mut &str) -> PResult<()> {
1229            ().parse_next(i)
1230        }
1231        assert_eq!(parser.parse_peek("abxsbsh"), Ok(("abxsbsh", ())));
1232        assert_eq!(parser.parse_peek("sdfjakdsas"), Ok(("sdfjakdsas", ())));
1233        assert_eq!(parser.parse_peek(""), Ok(("", ())));
1234    }
1235}