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