winnow/
parser.rs

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