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