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(input: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(input: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(input: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(input: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(input: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(input: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(input: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(input: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(input: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: &mut I| match peek((*input).clone()) {
1106 Ok((i: I, o: O)) => {
1107 *input = i;
1108 Ok(o)
1109 }
1110 Err(err: ErrMode) => 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}
1206