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