1 | //! Basic types to build the parsers |
2 | |
3 | use crate::ascii::Caseless as AsciiCaseless; |
4 | use crate::combinator::*; |
5 | #[cfg (feature = "unstable-recover" )] |
6 | use crate::error::FromRecoverableError; |
7 | use crate::error::{AddContext, FromExternalError, IResult, PResult, ParseError, ParserError}; |
8 | use crate::stream::{AsChar, Compare, Location, ParseSlice, Stream, StreamIsPartial}; |
9 | #[cfg (feature = "unstable-recover" )] |
10 | use 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] |
46 | pub 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 | |
708 | impl<'a, I, O, E, F> Parser<I, O, E> for F |
709 | where |
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 | /// ``` |
734 | impl<I, E> Parser<I, u8, E> for u8 |
735 | where |
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 | /// ``` |
761 | impl<I, E> Parser<I, <I as Stream>::Token, E> for char |
762 | where |
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 | /// ``` |
792 | impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8] |
793 | where |
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 | /// ``` |
824 | impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s [u8]> |
825 | where |
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 | /// ``` |
853 | impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N] |
854 | where |
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 | /// ``` |
885 | impl<'s, I, E: ParserError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> |
886 | for AsciiCaseless<&'s [u8; N]> |
887 | where |
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 | /// ``` |
915 | impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str |
916 | where |
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 | /// ``` |
947 | impl<'s, I, E: ParserError<I>> Parser<I, <I as Stream>::Slice, E> for AsciiCaseless<&'s str> |
948 | where |
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 | |
958 | impl<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 | |
965 | macro_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 | |
984 | macro_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" )] |
1001 | pub 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" )] |
1013 | impl<P, I, O, R, E> RecoverableParser<I, O, R, E> for P |
1014 | where |
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 | |
1062 | impl_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" )] |
1087 | use alloc::boxed::Box; |
1088 | |
1089 | #[cfg (feature = "alloc" )] |
1090 | impl<'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)] |
1099 | pub 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> |
1102 | where |
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)] |
1115 | mod 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 | |