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::{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::literal`][crate::token::literal]
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_take`][crate::binary::length_take] 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_take;
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_take(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_take;
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_take(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::Tag))));
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::literal;
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::Tag))));
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::Tag))));
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::literal;
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::Tag))));
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_take<'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_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
500 /// assert_eq!(length_take.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_take<'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_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
516 /// assert_eq!(length_take.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::Tag))));
731/// assert_eq!(parser.parse_peek(&b"bc"[..]), Err(ErrMode::Backtrack(InputError::new(&b"bc"[..], ErrorKind::Tag))));
732/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Tag))));
733/// ```
734impl<I, E> Parser<I, u8, E> for u8
735where
736 I: StreamIsPartial,
737 I: Stream,
738 I: Compare<u8>,
739 E: ParserError<I>,
740{
741 #[inline(always)]
742 fn parse_next(&mut self, i: &mut I) -> PResult<u8, E> {
743 crate::token::literal(*self).value(*self).parse_next(input:i)
744 }
745}
746
747/// This is a shortcut for [`one_of`][crate::token::one_of].
748///
749/// # Example
750///
751/// ```
752/// # use winnow::prelude::*;
753/// # use winnow::{error::ErrMode, error::{ErrorKind, InputError}};
754/// fn parser<'s>(i: &mut &'s str) -> PResult<char, InputError<&'s str>> {
755/// 'a'.parse_next(i)
756/// }
757/// assert_eq!(parser.parse_peek("abc"), Ok(("bc", 'a')));
758/// assert_eq!(parser.parse_peek(" abc"), Err(ErrMode::Backtrack(InputError::new(" abc", ErrorKind::Tag))));
759/// assert_eq!(parser.parse_peek("bc"), Err(ErrMode::Backtrack(InputError::new("bc", ErrorKind::Tag))));
760/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Tag))));
761/// ```
762impl<I, E> Parser<I, char, E> for char
763where
764 I: StreamIsPartial,
765 I: Stream,
766 I: Compare<char>,
767 E: ParserError<I>,
768{
769 #[inline(always)]
770 fn parse_next(&mut self, i: &mut I) -> PResult<char, E> {
771 crate::token::literal(*self).value(*self).parse_next(input:i)
772 }
773}
774
775/// This is a shortcut for [`literal`][crate::token::literal].
776///
777/// # Example
778/// ```rust
779/// # use winnow::prelude::*;
780/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
781/// # use winnow::combinator::alt;
782/// # use winnow::token::take;
783///
784/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
785/// alt((&"Hello"[..], take(5usize))).parse_next(s)
786/// }
787///
788/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
789/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
790/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
791/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
792/// ```
793impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8]
794where
795 I: Compare<&'s [u8]> + StreamIsPartial,
796 I: Stream,
797{
798 #[inline(always)]
799 fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
800 crate::token::literal(*self).parse_next(input:i)
801 }
802}
803
804/// This is a shortcut for [`literal`][crate::token::literal].
805///
806/// # Example
807/// ```rust
808/// # use winnow::prelude::*;
809/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
810/// # use winnow::combinator::alt;
811/// # use winnow::token::take;
812/// use winnow::ascii::Caseless;
813///
814/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
815/// alt((Caseless(&"hello"[..]), take(5usize))).parse_next(s)
816/// }
817///
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"HeLlo, World!"[..]), Ok((&b", World!"[..], &b"HeLlo"[..])));
821/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
822/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
823/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
824/// ```
825impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s [u8]>
826where
827 I: Compare<AsciiCaseless<&'s [u8]>> + StreamIsPartial,
828 I: Stream,
829{
830 #[inline(always)]
831 fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
832 crate::token::literal(*self).parse_next(input:i)
833 }
834}
835
836/// This is a shortcut for [`literal`][crate::token::literal].
837///
838/// # Example
839/// ```rust
840/// # use winnow::prelude::*;
841/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
842/// # use winnow::combinator::alt;
843/// # use winnow::token::take;
844///
845/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
846/// alt((b"Hello", take(5usize))).parse_next(s)
847/// }
848///
849/// assert_eq!(parser.parse_peek(&b"Hello, World!"[..]), Ok((&b", World!"[..], &b"Hello"[..])));
850/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
851/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
852/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
853/// ```
854impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N]
855where
856 I: Compare<&'s [u8; N]> + StreamIsPartial,
857 I: Stream,
858{
859 #[inline(always)]
860 fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
861 crate::token::literal(*self).parse_next(input:i)
862 }
863}
864
865/// This is a shortcut for [`literal`][crate::token::literal].
866///
867/// # Example
868/// ```rust
869/// # use winnow::prelude::*;
870/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, error::Needed};
871/// # use winnow::combinator::alt;
872/// # use winnow::token::take;
873/// use winnow::ascii::Caseless;
874///
875/// fn parser<'s>(s: &mut &'s [u8]) -> PResult<&'s [u8], InputError<&'s [u8]>> {
876/// alt((Caseless(b"hello"), take(5usize))).parse_next(s)
877/// }
878///
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"HeLlo, World!"[..]), Ok((&b", World!"[..], &b"HeLlo"[..])));
882/// assert_eq!(parser.parse_peek(&b"Something"[..]), Ok((&b"hing"[..], &b"Somet"[..])));
883/// assert_eq!(parser.parse_peek(&b"Some"[..]), Err(ErrMode::Backtrack(InputError::new(&b"Some"[..], ErrorKind::Slice))));
884/// assert_eq!(parser.parse_peek(&b""[..]), Err(ErrMode::Backtrack(InputError::new(&b""[..], ErrorKind::Slice))));
885/// ```
886impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E>
887 for AsciiCaseless<&'s [u8; N]>
888where
889 I: Compare<AsciiCaseless<&'s [u8; N]>> + StreamIsPartial,
890 I: Stream,
891{
892 #[inline(always)]
893 fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
894 crate::token::literal(*self).parse_next(input:i)
895 }
896}
897
898/// This is a shortcut for [`literal`][crate::token::literal].
899///
900/// # Example
901/// ```rust
902/// # use winnow::prelude::*;
903/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}};
904/// # use winnow::combinator::alt;
905/// # use winnow::token::take;
906///
907/// fn parser<'s>(s: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
908/// alt(("Hello", take(5usize))).parse_next(s)
909/// }
910///
911/// assert_eq!(parser.parse_peek("Hello, World!"), Ok((", World!", "Hello")));
912/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet")));
913/// assert_eq!(parser.parse_peek("Some"), Err(ErrMode::Backtrack(InputError::new("Some", ErrorKind::Slice))));
914/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Slice))));
915/// ```
916impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str
917where
918 I: Compare<&'s str> + StreamIsPartial,
919 I: Stream,
920{
921 #[inline(always)]
922 fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
923 crate::token::literal(*self).parse_next(input:i)
924 }
925}
926
927/// This is a shortcut for [`literal`][crate::token::literal].
928///
929/// # Example
930/// ```rust
931/// # use winnow::prelude::*;
932/// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}};
933/// # use winnow::combinator::alt;
934/// # use winnow::token::take;
935/// # use winnow::ascii::Caseless;
936///
937/// fn parser<'s>(s: &mut &'s str) -> PResult<&'s str, InputError<&'s str>> {
938/// alt((Caseless("hello"), take(5usize))).parse_next(s)
939/// }
940///
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("HeLlo, World!"), Ok((", World!", "HeLlo")));
944/// assert_eq!(parser.parse_peek("Something"), Ok(("hing", "Somet")));
945/// assert_eq!(parser.parse_peek("Some"), Err(ErrMode::Backtrack(InputError::new("Some", ErrorKind::Slice))));
946/// assert_eq!(parser.parse_peek(""), Err(ErrMode::Backtrack(InputError::new("", ErrorKind::Slice))));
947/// ```
948impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s str>
949where
950 I: Compare<AsciiCaseless<&'s str>> + StreamIsPartial,
951 I: Stream,
952{
953 #[inline(always)]
954 fn parse_next(&mut self, i: &mut I) -> PResult<<I as Stream>::Slice, E> {
955 crate::token::literal(*self).parse_next(input:i)
956 }
957}
958
959impl<I: Stream, E: ParserError<I>> Parser<I, (), E> for () {
960 #[inline(always)]
961 fn parse_next(&mut self, _i: &mut I) -> PResult<(), E> {
962 Ok(())
963 }
964}
965
966macro_rules! impl_parser_for_tuple {
967 ($($parser:ident $output:ident),+) => (
968 #[allow(non_snake_case)]
969 impl<I: Stream, $($output),+, E: ParserError<I>, $($parser),+> Parser<I, ($($output),+,), E> for ($($parser),+,)
970 where
971 $($parser: Parser<I, $output, E>),+
972 {
973 #[inline(always)]
974 fn parse_next(&mut self, i: &mut I) -> PResult<($($output),+,), E> {
975 let ($(ref mut $parser),+,) = *self;
976
977 $(let $output = $parser.parse_next(i)?;)+
978
979 Ok(($($output),+,))
980 }
981 }
982 )
983}
984
985macro_rules! impl_parser_for_tuples {
986 ($parser1:ident $output1:ident, $($parser:ident $output:ident),+) => {
987 impl_parser_for_tuples!(__impl $parser1 $output1; $($parser $output),+);
988 };
989 (__impl $($parser:ident $output:ident),+; $parser1:ident $output1:ident $(,$parser2:ident $output2:ident)*) => {
990 impl_parser_for_tuple!($($parser $output),+);
991 impl_parser_for_tuples!(__impl $($parser $output),+, $parser1 $output1; $($parser2 $output2),*);
992 };
993 (__impl $($parser:ident $output:ident),+;) => {
994 impl_parser_for_tuple!($($parser $output),+);
995 }
996}
997
998/// Collect all errors when parsing the input
999///
1000/// [`Parser`]s will need to use [`Recoverable<I, _>`] for their input.
1001#[cfg(feature = "unstable-recover")]
1002pub trait RecoverableParser<I, O, R, E> {
1003 /// Collect all errors when parsing the input
1004 ///
1005 /// If `self` fails, this acts like [`Parser::resume_after`] and returns `Ok(None)`.
1006 /// Generally, this should be avoided by using
1007 /// [`Parser::retry_after`] and [`Parser::resume_after`] throughout your parser.
1008 ///
1009 /// The empty `input` is returned to allow turning the errors into [`ParserError`]s.
1010 fn recoverable_parse(&mut self, input: I) -> (I, Option<O>, Vec<R>);
1011}
1012
1013#[cfg(feature = "unstable-recover")]
1014impl<P, I, O, R, E> RecoverableParser<I, O, R, E> for P
1015where
1016 P: Parser<Recoverable<I, R>, O, E>,
1017 I: Stream,
1018 I: StreamIsPartial,
1019 R: FromRecoverableError<Recoverable<I, R>, E>,
1020 R: crate::lib::std::fmt::Debug,
1021 E: FromRecoverableError<Recoverable<I, R>, E>,
1022 E: ParserError<Recoverable<I, R>>,
1023 E: crate::lib::std::fmt::Debug,
1024{
1025 #[inline]
1026 fn recoverable_parse(&mut self, input: I) -> (I, Option<O>, Vec<R>) {
1027 debug_assert!(
1028 !I::is_partial_supported(),
1029 "partial streams need to handle `ErrMode::Incomplete`"
1030 );
1031
1032 let start = input.checkpoint();
1033 let mut input = Recoverable::new(input);
1034 let start_token = input.checkpoint();
1035 let result = (
1036 self.by_ref(),
1037 crate::combinator::eof.resume_after(rest.void()),
1038 )
1039 .parse_next(&mut input);
1040
1041 let (o, err) = match result {
1042 Ok((o, _)) => (Some(o), None),
1043 Err(err) => {
1044 let err = err
1045 .into_inner()
1046 .expect("complete parsers should not report `ErrMode::Incomplete(_)`");
1047 let err_start = input.checkpoint();
1048 let err = R::from_recoverable_error(&start_token, &err_start, &input, err);
1049 (None, Some(err))
1050 }
1051 };
1052
1053 let (mut input, mut errs) = input.into_parts();
1054 input.reset(&start);
1055 if let Some(err) = err {
1056 errs.push(err);
1057 }
1058
1059 (input, o, errs)
1060 }
1061}
1062
1063impl_parser_for_tuples!(
1064 P1 O1,
1065 P2 O2,
1066 P3 O3,
1067 P4 O4,
1068 P5 O5,
1069 P6 O6,
1070 P7 O7,
1071 P8 O8,
1072 P9 O9,
1073 P10 O10,
1074 P11 O11,
1075 P12 O12,
1076 P13 O13,
1077 P14 O14,
1078 P15 O15,
1079 P16 O16,
1080 P17 O17,
1081 P18 O18,
1082 P19 O19,
1083 P20 O20,
1084 P21 O21
1085);
1086
1087#[cfg(feature = "alloc")]
1088use alloc::boxed::Box;
1089
1090#[cfg(feature = "alloc")]
1091impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> {
1092 #[inline(always)]
1093 fn parse_next(&mut self, i: &mut I) -> PResult<O, E> {
1094 (**self).parse_next(input:i)
1095 }
1096}
1097
1098/// Convert a [`Parser::parse_peek`] style parse function to be a [`Parser`]
1099#[inline(always)]
1100pub fn unpeek<'a, I, O, E>(
1101 mut peek: impl FnMut(I) -> IResult<I, O, E> + 'a,
1102) -> impl FnMut(&mut I) -> PResult<O, E>
1103where
1104 I: Clone,
1105{
1106 move |input: &mut I| match peek((*input).clone()) {
1107 Ok((i: I, o: O)) => {
1108 *input = i;
1109 Ok(o)
1110 }
1111 Err(err: ErrMode) => Err(err),
1112 }
1113}
1114
1115#[cfg(test)]
1116mod tests {
1117 use super::*;
1118 use crate::binary::be_u16;
1119 use crate::error::ErrMode;
1120 use crate::error::ErrorKind;
1121 use crate::error::InputError;
1122 use crate::error::Needed;
1123 use crate::token::take;
1124 use crate::Partial;
1125
1126 #[doc(hidden)]
1127 #[macro_export]
1128 macro_rules! assert_size (
1129 ($t:ty, $sz:expr) => (
1130 assert!($crate::lib::std::mem::size_of::<$t>() <= $sz, "{} <= {} failed", $crate::lib::std::mem::size_of::<$t>(), $sz);
1131 );
1132 );
1133
1134 #[test]
1135 #[cfg(target_pointer_width = "64")]
1136 fn size_test() {
1137 assert_size!(IResult<&[u8], &[u8], (&[u8], u32)>, 40);
1138 assert_size!(IResult<&str, &str, u32>, 40);
1139 assert_size!(Needed, 8);
1140 assert_size!(ErrMode<u32>, 16);
1141 assert_size!(ErrorKind, 1);
1142 }
1143
1144 #[test]
1145 fn err_map_test() {
1146 let e = ErrMode::Backtrack(1);
1147 assert_eq!(e.map(|v| v + 1), ErrMode::Backtrack(2));
1148 }
1149
1150 #[test]
1151 fn single_element_tuples() {
1152 use crate::ascii::alpha1;
1153 use crate::error::ErrorKind;
1154
1155 let mut parser = (alpha1,);
1156 assert_eq!(parser.parse_peek("abc123def"), Ok(("123def", ("abc",))));
1157 assert_eq!(
1158 parser.parse_peek("123def"),
1159 Err(ErrMode::Backtrack(InputError::new(
1160 "123def",
1161 ErrorKind::Slice
1162 )))
1163 );
1164 }
1165
1166 #[test]
1167 fn tuple_test() {
1168 #[allow(clippy::type_complexity)]
1169 fn tuple_3(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (u16, &[u8], &[u8])> {
1170 (be_u16, take(3u8), "fg").parse_peek(i)
1171 }
1172
1173 assert_eq!(
1174 tuple_3(Partial::new(&b"abcdefgh"[..])),
1175 Ok((
1176 Partial::new(&b"h"[..]),
1177 (0x6162u16, &b"cde"[..], &b"fg"[..])
1178 ))
1179 );
1180 assert_eq!(
1181 tuple_3(Partial::new(&b"abcd"[..])),
1182 Err(ErrMode::Incomplete(Needed::new(1)))
1183 );
1184 assert_eq!(
1185 tuple_3(Partial::new(&b"abcde"[..])),
1186 Err(ErrMode::Incomplete(Needed::new(2)))
1187 );
1188 assert_eq!(
1189 tuple_3(Partial::new(&b"abcdejk"[..])),
1190 Err(ErrMode::Backtrack(error_position!(
1191 &Partial::new(&b"jk"[..]),
1192 ErrorKind::Tag
1193 )))
1194 );
1195 }
1196
1197 #[test]
1198 fn unit_type() {
1199 fn parser(i: &mut &str) -> PResult<()> {
1200 ().parse_next(i)
1201 }
1202 assert_eq!(parser.parse_peek("abxsbsh"), Ok(("abxsbsh", ())));
1203 assert_eq!(parser.parse_peek("sdfjakdsas"), Ok(("sdfjakdsas", ())));
1204 assert_eq!(parser.parse_peek(""), Ok(("", ())));
1205 }
1206}
1207