1 | //! Basic types to build the parsers |
2 | |
3 | use crate::combinator::*; |
4 | use crate::error::{ContextError, FromExternalError, IResult, ParseError}; |
5 | use crate::stream::{AsChar, Compare, Location, Offset, ParseSlice, Stream, StreamIsPartial}; |
6 | |
7 | /// Core trait for parsing |
8 | /// |
9 | /// The simplest way to implement a `Parser` is with a function |
10 | /// ```rust |
11 | /// use winnow::prelude::*; |
12 | /// |
13 | /// fn success(input: &str) -> IResult<&str, ()> { |
14 | /// let output = (); |
15 | /// Ok((input, output)) |
16 | /// } |
17 | /// |
18 | /// let (input, output) = success.parse_next("Hello" ).unwrap(); |
19 | /// assert_eq!(input, "Hello" ); // We didn't consume any input |
20 | /// ``` |
21 | /// |
22 | /// which can be made stateful by returning a function |
23 | /// ```rust |
24 | /// use winnow::prelude::*; |
25 | /// |
26 | /// fn success<O: Clone>(output: O) -> impl FnMut(&str) -> IResult<&str, O> { |
27 | /// move |input: &str| { |
28 | /// let output = output.clone(); |
29 | /// Ok((input, output)) |
30 | /// } |
31 | /// } |
32 | /// |
33 | /// let (input, output) = success("World" ).parse_next("Hello" ).unwrap(); |
34 | /// assert_eq!(input, "Hello" ); // We didn't consume any input |
35 | /// assert_eq!(output, "World" ); |
36 | /// ``` |
37 | /// |
38 | /// Additionally, some basic types implement `Parser` as well, including |
39 | /// - `u8` and `char`, see [`winnow::token::one_of`][crate::token::one_of] |
40 | /// - `&[u8]` and `&str`, see [`winnow::token::tag`][crate::token::tag] |
41 | pub trait Parser<I, O, E> { |
42 | /// Parse all of `input`, generating `O` from it |
43 | #[inline ] |
44 | fn parse(&mut self, input: I) -> Result<O, E> |
45 | where |
46 | I: Stream, |
47 | // Force users to deal with `Incomplete` when `StreamIsPartial<true>` |
48 | I: StreamIsPartial, |
49 | I: Clone, |
50 | E: ParseError<I>, |
51 | { |
52 | #![allow (deprecated)] |
53 | use crate::error::FinishIResult; |
54 | self.parse_next(input).finish() |
55 | } |
56 | |
57 | /// Take tokens from the [`Stream`], turning it into the output |
58 | /// |
59 | /// This includes advancing the [`Stream`] to the next location. |
60 | fn parse_next(&mut self, input: I) -> IResult<I, O, E>; |
61 | |
62 | /// Treat `&mut Self` as a parser |
63 | /// |
64 | /// This helps when needing to move a `Parser` when all you have is a `&mut Parser`. |
65 | /// |
66 | /// # Example |
67 | /// |
68 | /// Because parsers are `FnMut`, they can be called multiple times. This prevents moving `f` |
69 | /// into [`length_data`][crate::binary::length_data] and `g` into |
70 | /// [`Parser::complete_err`]: |
71 | /// ```rust,compile_fail |
72 | /// # use winnow::prelude::*; |
73 | /// # use winnow::IResult; |
74 | /// # use winnow::Parser; |
75 | /// # use winnow::error::ParseError; |
76 | /// # use winnow::binary::length_data; |
77 | /// pub fn length_value<'i, O, E: ParseError<&'i [u8]>>( |
78 | /// mut f: impl Parser<&'i [u8], usize, E>, |
79 | /// mut g: impl Parser<&'i [u8], O, E> |
80 | /// ) -> impl FnMut(&'i [u8]) -> IResult<&'i [u8], O, E> { |
81 | /// move |i: &'i [u8]| { |
82 | /// let (i, data) = length_data(f).parse_next(i)?; |
83 | /// let (_, o) = g.complete().parse_next(data)?; |
84 | /// Ok((i, o)) |
85 | /// } |
86 | /// } |
87 | /// ``` |
88 | /// |
89 | /// By adding `by_ref`, we can make this work: |
90 | /// ```rust |
91 | /// # use winnow::prelude::*; |
92 | /// # use winnow::IResult; |
93 | /// # use winnow::Parser; |
94 | /// # use winnow::error::ParseError; |
95 | /// # use winnow::binary::length_data; |
96 | /// pub fn length_value<'i, O, E: ParseError<&'i [u8]>>( |
97 | /// mut f: impl Parser<&'i [u8], usize, E>, |
98 | /// mut g: impl Parser<&'i [u8], O, E> |
99 | /// ) -> impl FnMut(&'i [u8]) -> IResult<&'i [u8], O, E> { |
100 | /// move |i: &'i [u8]| { |
101 | /// let (i, data) = length_data(f.by_ref()).parse_next(i)?; |
102 | /// let (_, o) = g.by_ref().complete_err().parse_next(data)?; |
103 | /// Ok((i, o)) |
104 | /// } |
105 | /// } |
106 | /// ``` |
107 | fn by_ref(&mut self) -> ByRef<'_, Self> |
108 | where |
109 | Self: core::marker::Sized, |
110 | { |
111 | ByRef::new(self) |
112 | } |
113 | |
114 | /// Produce the provided value |
115 | /// |
116 | /// # Example |
117 | /// |
118 | /// ```rust |
119 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
120 | /// use winnow::ascii::alpha1; |
121 | /// # fn main() { |
122 | /// |
123 | /// let mut parser = alpha1.value(1234); |
124 | /// |
125 | /// assert_eq!(parser.parse_next("abcd" ), Ok(("" , 1234))); |
126 | /// assert_eq!(parser.parse_next("123abcd;" ), Err(ErrMode::Backtrack(Error::new("123abcd;" , ErrorKind::Slice)))); |
127 | /// # } |
128 | /// ``` |
129 | #[doc (alias = "to" )] |
130 | fn value<O2>(self, val: O2) -> Value<Self, I, O, O2, E> |
131 | where |
132 | Self: core::marker::Sized, |
133 | O2: Clone, |
134 | { |
135 | Value::new(self, val) |
136 | } |
137 | |
138 | /// Discards the output of the `Parser` |
139 | /// |
140 | /// # Example |
141 | /// |
142 | /// ```rust |
143 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
144 | /// use winnow::ascii::alpha1; |
145 | /// # fn main() { |
146 | /// |
147 | /// let mut parser = alpha1.void(); |
148 | /// |
149 | /// assert_eq!(parser.parse_next("abcd" ), Ok(("" , ()))); |
150 | /// assert_eq!(parser.parse_next("123abcd;" ), Err(ErrMode::Backtrack(Error::new("123abcd;" , ErrorKind::Slice)))); |
151 | /// # } |
152 | /// ``` |
153 | fn void(self) -> Void<Self, I, O, E> |
154 | where |
155 | Self: core::marker::Sized, |
156 | { |
157 | Void::new(self) |
158 | } |
159 | |
160 | /// Convert the parser's output to another type using [`std::convert::From`] |
161 | /// |
162 | /// # Example |
163 | /// |
164 | /// ```rust |
165 | /// # use winnow::IResult; |
166 | /// # use winnow::Parser; |
167 | /// use winnow::ascii::alpha1; |
168 | /// # fn main() { |
169 | /// |
170 | /// fn parser1(i: &str) -> IResult<&str, &str> { |
171 | /// alpha1(i) |
172 | /// } |
173 | /// |
174 | /// let mut parser2 = parser1.output_into(); |
175 | /// |
176 | /// // the parser converts the &str output of the child parser into a Vec<u8> |
177 | /// let bytes: IResult<&str, Vec<u8>> = parser2.parse_next("abcd" ); |
178 | /// assert_eq!(bytes, Ok(("" , vec![97, 98, 99, 100]))); |
179 | /// # } |
180 | /// ``` |
181 | fn output_into<O2>(self) -> OutputInto<Self, I, O, O2, E> |
182 | where |
183 | Self: core::marker::Sized, |
184 | O: Into<O2>, |
185 | { |
186 | OutputInto::new(self) |
187 | } |
188 | |
189 | /// Produce the consumed input as produced value. |
190 | /// |
191 | /// # Example |
192 | /// |
193 | /// ```rust |
194 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
195 | /// use winnow::ascii::{alpha1}; |
196 | /// use winnow::combinator::separated_pair; |
197 | /// # fn main() { |
198 | /// |
199 | /// let mut parser = separated_pair(alpha1, ',' , alpha1).recognize(); |
200 | /// |
201 | /// assert_eq!(parser.parse_next("abcd,efgh" ), Ok(("" , "abcd,efgh" ))); |
202 | /// assert_eq!(parser.parse_next("abcd;" ),Err(ErrMode::Backtrack(Error::new(";" , ErrorKind::Verify)))); |
203 | /// # } |
204 | /// ``` |
205 | #[doc (alias = "concat" )] |
206 | fn recognize(self) -> Recognize<Self, I, O, E> |
207 | where |
208 | Self: core::marker::Sized, |
209 | I: Stream + Offset, |
210 | { |
211 | Recognize::new(self) |
212 | } |
213 | |
214 | /// Produce the consumed input with the output |
215 | /// |
216 | /// Functions similarly to [recognize][Parser::recognize] except it |
217 | /// returns the parser output as well. |
218 | /// |
219 | /// This can be useful especially in cases where the output is not the same type |
220 | /// as the input, or the input is a user defined type. |
221 | /// |
222 | /// Returned tuple is of the format `(produced output, consumed input)`. |
223 | /// |
224 | /// # Example |
225 | /// |
226 | /// ```rust |
227 | /// # use winnow::prelude::*; |
228 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult}; |
229 | /// use winnow::ascii::{alpha1}; |
230 | /// use winnow::token::tag; |
231 | /// use winnow::combinator::separated_pair; |
232 | /// |
233 | /// fn inner_parser(input: &str) -> IResult<&str, bool> { |
234 | /// "1234" .value(true).parse_next(input) |
235 | /// } |
236 | /// |
237 | /// # fn main() { |
238 | /// |
239 | /// let mut consumed_parser = separated_pair(alpha1, ',' , alpha1).value(true).with_recognized(); |
240 | /// |
241 | /// assert_eq!(consumed_parser.parse_next("abcd,efgh1" ), Ok(("1" , (true, "abcd,efgh" )))); |
242 | /// assert_eq!(consumed_parser.parse_next("abcd;" ),Err(ErrMode::Backtrack(Error::new(";" , ErrorKind::Verify)))); |
243 | /// |
244 | /// // the second output (representing the consumed input) |
245 | /// // should be the same as that of the `recognize` parser. |
246 | /// let mut recognize_parser = inner_parser.recognize(); |
247 | /// let mut consumed_parser = inner_parser.with_recognized().map(|(output, consumed)| consumed); |
248 | /// |
249 | /// assert_eq!(recognize_parser.parse_next("1234" ), consumed_parser.parse_next("1234" )); |
250 | /// assert_eq!(recognize_parser.parse_next("abcd" ), consumed_parser.parse_next("abcd" )); |
251 | /// # } |
252 | /// ``` |
253 | #[doc (alias = "consumed" )] |
254 | fn with_recognized(self) -> WithRecognized<Self, I, O, E> |
255 | where |
256 | Self: core::marker::Sized, |
257 | I: Stream + Offset, |
258 | { |
259 | WithRecognized::new(self) |
260 | } |
261 | |
262 | /// Produce the location of the consumed input as produced value. |
263 | /// |
264 | /// # Example |
265 | /// |
266 | /// ```rust |
267 | /// # use winnow::prelude::*; |
268 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, stream::Stream}; |
269 | /// use winnow::stream::Located; |
270 | /// use winnow::ascii::alpha1; |
271 | /// use winnow::combinator::separated_pair; |
272 | /// |
273 | /// let mut parser = separated_pair(alpha1.span(), ',' , alpha1.span()); |
274 | /// |
275 | /// assert_eq!(parser.parse(Located::new("abcd,efgh" )), Ok((0..4, 5..9))); |
276 | /// assert_eq!(parser.parse_next(Located::new("abcd;" )),Err(ErrMode::Backtrack(Error::new(Located::new("abcd;" ).next_slice(4).0, ErrorKind::Verify)))); |
277 | /// ``` |
278 | fn span(self) -> Span<Self, I, O, E> |
279 | where |
280 | Self: core::marker::Sized, |
281 | I: Stream + Location, |
282 | { |
283 | Span::new(self) |
284 | } |
285 | |
286 | /// Produce the location of consumed input with the output |
287 | /// |
288 | /// Functions similarly to [`Parser::span`] except it |
289 | /// returns the parser output as well. |
290 | /// |
291 | /// This can be useful especially in cases where the output is not the same type |
292 | /// as the input, or the input is a user defined type. |
293 | /// |
294 | /// Returned tuple is of the format `(produced output, consumed input)`. |
295 | /// |
296 | /// # Example |
297 | /// |
298 | /// ```rust |
299 | /// # use winnow::prelude::*; |
300 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, stream::Stream}; |
301 | /// use winnow::stream::Located; |
302 | /// use winnow::ascii::alpha1; |
303 | /// use winnow::token::tag; |
304 | /// use winnow::combinator::separated_pair; |
305 | /// |
306 | /// fn inner_parser(input: Located<&str>) -> IResult<Located<&str>, bool> { |
307 | /// "1234" .value(true).parse_next(input) |
308 | /// } |
309 | /// |
310 | /// # fn main() { |
311 | /// |
312 | /// let mut consumed_parser = separated_pair(alpha1.value(1).with_span(), ',' , alpha1.value(2).with_span()); |
313 | /// |
314 | /// assert_eq!(consumed_parser.parse(Located::new("abcd,efgh" )), Ok(((1, 0..4), (2, 5..9)))); |
315 | /// assert_eq!(consumed_parser.parse_next(Located::new("abcd;" )),Err(ErrMode::Backtrack(Error::new(Located::new("abcd;" ).next_slice(4).0, ErrorKind::Verify)))); |
316 | /// |
317 | /// // the second output (representing the consumed input) |
318 | /// // should be the same as that of the `span` parser. |
319 | /// let mut recognize_parser = inner_parser.span(); |
320 | /// let mut consumed_parser = inner_parser.with_span().map(|(output, consumed)| consumed); |
321 | /// |
322 | /// assert_eq!(recognize_parser.parse_next(Located::new("1234" )), consumed_parser.parse_next(Located::new("1234" ))); |
323 | /// assert_eq!(recognize_parser.parse_next(Located::new("abcd" )), consumed_parser.parse_next(Located::new("abcd" ))); |
324 | /// # } |
325 | /// ``` |
326 | fn with_span(self) -> WithSpan<Self, I, O, E> |
327 | where |
328 | Self: core::marker::Sized, |
329 | I: Stream + Location, |
330 | { |
331 | WithSpan::new(self) |
332 | } |
333 | |
334 | /// Maps a function over the output of a parser |
335 | /// |
336 | /// # Example |
337 | /// |
338 | /// ```rust |
339 | /// use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult,Parser}; |
340 | /// use winnow::ascii::digit1; |
341 | /// # fn main() { |
342 | /// |
343 | /// let mut parser = digit1.map(|s: &str| s.len()); |
344 | /// |
345 | /// // the parser will count how many characters were returned by digit1 |
346 | /// assert_eq!(parser.parse_next("123456" ), Ok(("" , 6))); |
347 | /// |
348 | /// // this will fail if digit1 fails |
349 | /// assert_eq!(parser.parse_next("abc" ), Err(ErrMode::Backtrack(Error::new("abc" , ErrorKind::Slice)))); |
350 | /// # } |
351 | /// ``` |
352 | fn map<G, O2>(self, map: G) -> Map<Self, G, I, O, O2, E> |
353 | where |
354 | G: Fn(O) -> O2, |
355 | Self: core::marker::Sized, |
356 | { |
357 | Map::new(self, map) |
358 | } |
359 | |
360 | /// Applies a function returning a `Result` over the output of a parser. |
361 | /// |
362 | /// # Example |
363 | /// |
364 | /// ```rust |
365 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
366 | /// use winnow::ascii::digit1; |
367 | /// # fn main() { |
368 | /// |
369 | /// let mut parse = digit1.try_map(|s: &str| s.parse::<u8>()); |
370 | /// |
371 | /// // the parser will convert the result of digit1 to a number |
372 | /// assert_eq!(parse.parse_next("123" ), Ok(("" , 123))); |
373 | /// |
374 | /// // this will fail if digit1 fails |
375 | /// assert_eq!(parse.parse_next("abc" ), Err(ErrMode::Backtrack(Error::new("abc" , ErrorKind::Slice)))); |
376 | /// |
377 | /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`) |
378 | /// assert_eq!(parse.parse_next("123456" ), Err(ErrMode::Backtrack(Error::new("123456" , ErrorKind::Verify)))); |
379 | /// # } |
380 | /// ``` |
381 | fn try_map<G, O2, E2>(self, map: G) -> TryMap<Self, G, I, O, O2, E, E2> |
382 | where |
383 | Self: core::marker::Sized, |
384 | G: FnMut(O) -> Result<O2, E2>, |
385 | I: Clone, |
386 | E: FromExternalError<I, E2>, |
387 | { |
388 | TryMap::new(self, map) |
389 | } |
390 | |
391 | /// Deprecated, see [`Parser::try_map`] |
392 | #[deprecated (since = "0.4.2" , note = "Replaced with `Parser::try_map`" )] |
393 | fn map_res<G, O2, E2>(self, map: G) -> MapRes<Self, G, I, O, O2, E, E2> |
394 | where |
395 | Self: core::marker::Sized, |
396 | G: FnMut(O) -> Result<O2, E2>, |
397 | I: Clone, |
398 | E: FromExternalError<I, E2>, |
399 | { |
400 | self.try_map(map) |
401 | } |
402 | |
403 | /// Apply both [`Parser::verify`] and [`Parser::map`]. |
404 | /// |
405 | /// # Example |
406 | /// |
407 | /// ```rust |
408 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
409 | /// use winnow::ascii::digit1; |
410 | /// # fn main() { |
411 | /// |
412 | /// let mut parse = digit1.verify_map(|s: &str| s.parse::<u8>().ok()); |
413 | /// |
414 | /// // the parser will convert the result of digit1 to a number |
415 | /// assert_eq!(parse.parse_next("123" ), Ok(("" , 123))); |
416 | /// |
417 | /// // this will fail if digit1 fails |
418 | /// assert_eq!(parse.parse_next("abc" ), Err(ErrMode::Backtrack(Error::new("abc" , ErrorKind::Slice)))); |
419 | /// |
420 | /// // this will fail if the mapped function fails (a `u8` is too small to hold `123456`) |
421 | /// assert_eq!(parse.parse_next("123456" ), Err(ErrMode::Backtrack(Error::new("123456" , ErrorKind::Verify)))); |
422 | /// # } |
423 | /// ``` |
424 | #[doc (alias = "satisfy_map" )] |
425 | #[doc (alias = "filter_map" )] |
426 | #[doc (alias = "map_opt" )] |
427 | fn verify_map<G, O2>(self, map: G) -> VerifyMap<Self, G, I, O, O2, E> |
428 | where |
429 | Self: core::marker::Sized, |
430 | G: FnMut(O) -> Option<O2>, |
431 | I: Clone, |
432 | E: ParseError<I>, |
433 | { |
434 | VerifyMap::new(self, map) |
435 | } |
436 | |
437 | /// Creates a parser from the output of this one |
438 | /// |
439 | /// # Example |
440 | /// |
441 | /// ```rust |
442 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
443 | /// use winnow::token::take; |
444 | /// use winnow::binary::u8; |
445 | /// |
446 | /// fn length_data(input: &[u8]) -> IResult<&[u8], &[u8]> { |
447 | /// u8.flat_map(take).parse_next(input) |
448 | /// } |
449 | /// |
450 | /// assert_eq!(length_data.parse_next(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..]))); |
451 | /// assert_eq!(length_data.parse_next(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(Error::new(&[0, 1, 2][..], ErrorKind::Slice)))); |
452 | /// ``` |
453 | /// |
454 | /// which is the same as |
455 | /// ```rust |
456 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
457 | /// use winnow::token::take; |
458 | /// use winnow::binary::u8; |
459 | /// |
460 | /// fn length_data(input: &[u8]) -> IResult<&[u8], &[u8]> { |
461 | /// let (input, length) = u8.parse_next(input)?; |
462 | /// let (input, data) = take(length).parse_next(input)?; |
463 | /// Ok((input, data)) |
464 | /// } |
465 | /// |
466 | /// assert_eq!(length_data.parse_next(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..]))); |
467 | /// assert_eq!(length_data.parse_next(&[4, 0, 1, 2][..]), Err(ErrMode::Backtrack(Error::new(&[0, 1, 2][..], ErrorKind::Slice)))); |
468 | /// ``` |
469 | fn flat_map<G, H, O2>(self, map: G) -> FlatMap<Self, G, H, I, O, O2, E> |
470 | where |
471 | Self: core::marker::Sized, |
472 | G: FnMut(O) -> H, |
473 | H: Parser<I, O2, E>, |
474 | { |
475 | FlatMap::new(self, map) |
476 | } |
477 | |
478 | /// Applies a second parser over the output of the first one |
479 | /// |
480 | /// # Example |
481 | /// |
482 | /// ```rust |
483 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
484 | /// use winnow::ascii::digit1; |
485 | /// use winnow::token::take; |
486 | /// # fn main() { |
487 | /// |
488 | /// let mut digits = take(5u8).and_then(digit1); |
489 | /// |
490 | /// assert_eq!(digits.parse_next("12345" ), Ok(("" , "12345" ))); |
491 | /// assert_eq!(digits.parse_next("123ab" ), Ok(("" , "123" ))); |
492 | /// assert_eq!(digits.parse_next("123" ), Err(ErrMode::Backtrack(Error::new("123" , ErrorKind::Slice)))); |
493 | /// # } |
494 | /// ``` |
495 | fn and_then<G, O2>(self, inner: G) -> AndThen<Self, G, I, O, O2, E> |
496 | where |
497 | Self: core::marker::Sized, |
498 | G: Parser<O, O2, E>, |
499 | O: StreamIsPartial, |
500 | { |
501 | AndThen::new(self, inner) |
502 | } |
503 | |
504 | /// Apply [`std::str::FromStr`] to the output of the parser |
505 | /// |
506 | /// # Example |
507 | /// |
508 | /// ```rust |
509 | /// # use winnow::prelude::*; |
510 | /// use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult,Parser}; |
511 | /// use winnow::ascii::digit1; |
512 | /// |
513 | /// fn parser(input: &str) -> IResult<&str, u64> { |
514 | /// digit1.parse_to().parse_next(input) |
515 | /// } |
516 | /// |
517 | /// // the parser will count how many characters were returned by digit1 |
518 | /// assert_eq!(parser.parse_next("123456" ), Ok(("" , 123456))); |
519 | /// |
520 | /// // this will fail if digit1 fails |
521 | /// assert_eq!(parser.parse_next("abc" ), Err(ErrMode::Backtrack(Error::new("abc" , ErrorKind::Slice)))); |
522 | /// ``` |
523 | #[doc (alias = "from_str" )] |
524 | fn parse_to<O2>(self) -> ParseTo<Self, I, O, O2, E> |
525 | where |
526 | Self: core::marker::Sized, |
527 | I: Stream, |
528 | O: ParseSlice<O2>, |
529 | E: ParseError<I>, |
530 | { |
531 | ParseTo::new(self) |
532 | } |
533 | |
534 | /// Returns the output of the child parser if it satisfies a verification function. |
535 | /// |
536 | /// The verification function takes as argument a reference to the output of the |
537 | /// parser. |
538 | /// |
539 | /// # Example |
540 | /// |
541 | /// ```rust |
542 | /// # use winnow::{error::ErrMode,error::ErrorKind, error::Error, IResult, Parser}; |
543 | /// # use winnow::ascii::alpha1; |
544 | /// # fn main() { |
545 | /// |
546 | /// let mut parser = alpha1.verify(|s: &str| s.len() == 4); |
547 | /// |
548 | /// assert_eq!(parser.parse_next("abcd" ), Ok(("" , "abcd" ))); |
549 | /// assert_eq!(parser.parse_next("abcde" ), Err(ErrMode::Backtrack(Error::new("abcde" , ErrorKind::Verify)))); |
550 | /// assert_eq!(parser.parse_next("123abcd;" ),Err(ErrMode::Backtrack(Error::new("123abcd;" , ErrorKind::Slice)))); |
551 | /// # } |
552 | /// ``` |
553 | #[doc (alias = "satisfy" )] |
554 | #[doc (alias = "filter" )] |
555 | fn verify<G, O2>(self, filter: G) -> Verify<Self, G, I, O, O2, E> |
556 | where |
557 | Self: core::marker::Sized, |
558 | G: Fn(&O2) -> bool, |
559 | I: Clone, |
560 | O: crate::lib::std::borrow::Borrow<O2>, |
561 | O2: ?Sized, |
562 | E: ParseError<I>, |
563 | { |
564 | Verify::new(self, filter) |
565 | } |
566 | |
567 | /// If parsing fails, add context to the error |
568 | /// |
569 | /// This is used mainly to add user friendly information |
570 | /// to errors when backtracking through a parse tree. |
571 | #[doc (alias = "labelled" )] |
572 | fn context<C>(self, context: C) -> Context<Self, I, O, E, C> |
573 | where |
574 | Self: core::marker::Sized, |
575 | I: Stream, |
576 | E: ContextError<I, C>, |
577 | C: Clone + crate::lib::std::fmt::Debug, |
578 | { |
579 | Context::new(self, context) |
580 | } |
581 | |
582 | /// Transforms [`Incomplete`][crate::error::ErrMode::Incomplete] into [`Backtrack`][crate::error::ErrMode::Backtrack] |
583 | /// |
584 | /// # Example |
585 | /// |
586 | /// ```rust |
587 | /// # use winnow::{error::ErrMode, error::ErrorKind, error::Error, IResult, stream::Partial, Parser}; |
588 | /// # use winnow::token::take; |
589 | /// # fn main() { |
590 | /// |
591 | /// let mut parser = take(5u8).complete_err(); |
592 | /// |
593 | /// assert_eq!(parser.parse_next(Partial::new("abcdefg" )), Ok((Partial::new("fg" ), "abcde" ))); |
594 | /// assert_eq!(parser.parse_next(Partial::new("abcd" )), Err(ErrMode::Backtrack(Error::new(Partial::new("abcd" ), ErrorKind::Complete)))); |
595 | /// # } |
596 | /// ``` |
597 | fn complete_err(self) -> CompleteErr<Self> |
598 | where |
599 | Self: core::marker::Sized, |
600 | { |
601 | CompleteErr::new(self) |
602 | } |
603 | |
604 | /// Convert the parser's error to another type using [`std::convert::From`] |
605 | fn err_into<E2>(self) -> ErrInto<Self, I, O, E, E2> |
606 | where |
607 | Self: core::marker::Sized, |
608 | E: Into<E2>, |
609 | { |
610 | ErrInto::new(self) |
611 | } |
612 | } |
613 | |
614 | impl<'a, I, O, E, F> Parser<I, O, E> for F |
615 | where |
616 | F: FnMut(I) -> IResult<I, O, E> + 'a, |
617 | { |
618 | #[inline (always)] |
619 | fn parse_next(&mut self, i: I) -> IResult<I, O, E> { |
620 | self(i) |
621 | } |
622 | } |
623 | |
624 | /// This is a shortcut for [`one_of`][crate::token::one_of]. |
625 | /// |
626 | /// # Example |
627 | /// |
628 | /// ``` |
629 | /// # use winnow::prelude::*; |
630 | /// # use winnow::{error::ErrMode, error::{ErrorKind, Error}}; |
631 | /// fn parser(i: &[u8]) -> IResult<&[u8], u8> { |
632 | /// b'a' .parse_next(i) |
633 | /// } |
634 | /// assert_eq!(parser(&b"abc" [..]), Ok((&b"bc" [..], b'a' ))); |
635 | /// assert_eq!(parser(&b" abc" [..]), Err(ErrMode::Backtrack(Error::new(&b" abc" [..], ErrorKind::Verify)))); |
636 | /// assert_eq!(parser(&b"bc" [..]), Err(ErrMode::Backtrack(Error::new(&b"bc" [..], ErrorKind::Verify)))); |
637 | /// assert_eq!(parser(&b"" [..]), Err(ErrMode::Backtrack(Error::new(&b"" [..], ErrorKind::Token)))); |
638 | /// ``` |
639 | impl<I, E> Parser<I, u8, E> for u8 |
640 | where |
641 | I: StreamIsPartial, |
642 | I: Stream<Token = u8>, |
643 | E: ParseError<I>, |
644 | { |
645 | #[inline (always)] |
646 | fn parse_next(&mut self, i: I) -> IResult<I, u8, E> { |
647 | crate::token::one_of(*self).parse_next(input:i) |
648 | } |
649 | } |
650 | |
651 | /// This is a shortcut for [`one_of`][crate::token::one_of]. |
652 | /// |
653 | /// # Example |
654 | /// |
655 | /// ``` |
656 | /// # use winnow::prelude::*; |
657 | /// # use winnow::{error::ErrMode, error::{ErrorKind, Error}}; |
658 | /// fn parser(i: &str) -> IResult<&str, char> { |
659 | /// 'a' .parse_next(i) |
660 | /// } |
661 | /// assert_eq!(parser("abc" ), Ok(("bc" , 'a' ))); |
662 | /// assert_eq!(parser(" abc" ), Err(ErrMode::Backtrack(Error::new(" abc" , ErrorKind::Verify)))); |
663 | /// assert_eq!(parser("bc" ), Err(ErrMode::Backtrack(Error::new("bc" , ErrorKind::Verify)))); |
664 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Token)))); |
665 | /// ``` |
666 | impl<I, E> Parser<I, <I as Stream>::Token, E> for char |
667 | where |
668 | I: StreamIsPartial, |
669 | I: Stream, |
670 | <I as Stream>::Token: AsChar + Copy, |
671 | E: ParseError<I>, |
672 | { |
673 | #[inline (always)] |
674 | fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Token, E> { |
675 | crate::token::one_of(*self).parse_next(input:i) |
676 | } |
677 | } |
678 | |
679 | /// This is a shortcut for [`tag`][crate::token::tag]. |
680 | /// |
681 | /// # Example |
682 | /// ```rust |
683 | /// # use winnow::prelude::*; |
684 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
685 | /// # use winnow::combinator::alt; |
686 | /// # use winnow::token::take; |
687 | /// |
688 | /// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { |
689 | /// alt((&"Hello" [..], take(5usize))).parse_next(s) |
690 | /// } |
691 | /// |
692 | /// assert_eq!(parser(&b"Hello, World!" [..]), Ok((&b", World!" [..], &b"Hello" [..]))); |
693 | /// assert_eq!(parser(&b"Something" [..]), Ok((&b"hing" [..], &b"Somet" [..]))); |
694 | /// assert_eq!(parser(&b"Some" [..]), Err(ErrMode::Backtrack(Error::new(&b"Some" [..], ErrorKind::Slice)))); |
695 | /// assert_eq!(parser(&b"" [..]), Err(ErrMode::Backtrack(Error::new(&b"" [..], ErrorKind::Slice)))); |
696 | /// ``` |
697 | impl<'s, I, E: ParseError<I>> Parser<I, <I as Stream>::Slice, E> for &'s [u8] |
698 | where |
699 | I: Compare<&'s [u8]> + StreamIsPartial, |
700 | I: Stream, |
701 | { |
702 | #[inline (always)] |
703 | fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { |
704 | crate::token::tag(*self).parse_next(input:i) |
705 | } |
706 | } |
707 | |
708 | /// This is a shortcut for [`tag`][crate::token::tag]. |
709 | /// |
710 | /// # Example |
711 | /// ```rust |
712 | /// # use winnow::prelude::*; |
713 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}, error::Needed}; |
714 | /// # use winnow::combinator::alt; |
715 | /// # use winnow::token::take; |
716 | /// |
717 | /// fn parser(s: &[u8]) -> IResult<&[u8], &[u8]> { |
718 | /// alt((b"Hello" , take(5usize))).parse_next(s) |
719 | /// } |
720 | /// |
721 | /// assert_eq!(parser(&b"Hello, World!" [..]), Ok((&b", World!" [..], &b"Hello" [..]))); |
722 | /// assert_eq!(parser(&b"Something" [..]), Ok((&b"hing" [..], &b"Somet" [..]))); |
723 | /// assert_eq!(parser(&b"Some" [..]), Err(ErrMode::Backtrack(Error::new(&b"Some" [..], ErrorKind::Slice)))); |
724 | /// assert_eq!(parser(&b"" [..]), Err(ErrMode::Backtrack(Error::new(&b"" [..], ErrorKind::Slice)))); |
725 | /// ``` |
726 | impl<'s, I, E: ParseError<I>, const N: usize> Parser<I, <I as Stream>::Slice, E> for &'s [u8; N] |
727 | where |
728 | I: Compare<&'s [u8; N]> + StreamIsPartial, |
729 | I: Stream, |
730 | { |
731 | #[inline (always)] |
732 | fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { |
733 | crate::token::tag(*self).parse_next(input:i) |
734 | } |
735 | } |
736 | |
737 | /// This is a shortcut for [`tag`][crate::token::tag]. |
738 | /// |
739 | /// # Example |
740 | /// ```rust |
741 | /// # use winnow::prelude::*; |
742 | /// # use winnow::{error::ErrMode, error::{Error, ErrorKind}}; |
743 | /// # use winnow::combinator::alt; |
744 | /// # use winnow::token::take; |
745 | /// |
746 | /// fn parser(s: &str) -> IResult<&str, &str> { |
747 | /// alt(("Hello" , take(5usize))).parse_next(s) |
748 | /// } |
749 | /// |
750 | /// assert_eq!(parser("Hello, World!" ), Ok((", World!" , "Hello" ))); |
751 | /// assert_eq!(parser("Something" ), Ok(("hing" , "Somet" ))); |
752 | /// assert_eq!(parser("Some" ), Err(ErrMode::Backtrack(Error::new("Some" , ErrorKind::Slice)))); |
753 | /// assert_eq!(parser("" ), Err(ErrMode::Backtrack(Error::new("" , ErrorKind::Slice)))); |
754 | /// ``` |
755 | impl<'s, I, E: ParseError<I>> Parser<I, <I as Stream>::Slice, E> for &'s str |
756 | where |
757 | I: Compare<&'s str> + StreamIsPartial, |
758 | I: Stream, |
759 | { |
760 | #[inline (always)] |
761 | fn parse_next(&mut self, i: I) -> IResult<I, <I as Stream>::Slice, E> { |
762 | crate::token::tag(*self).parse_next(input:i) |
763 | } |
764 | } |
765 | |
766 | impl<I, E: ParseError<I>> Parser<I, (), E> for () { |
767 | #[inline (always)] |
768 | fn parse_next(&mut self, i: I) -> IResult<I, (), E> { |
769 | Ok((i, ())) |
770 | } |
771 | } |
772 | |
773 | macro_rules! impl_parser_for_tuple { |
774 | ($($parser:ident $output:ident),+) => ( |
775 | #[allow(non_snake_case)] |
776 | impl<I, $($output),+, E: ParseError<I>, $($parser),+> Parser<I, ($($output),+,), E> for ($($parser),+,) |
777 | where |
778 | $($parser: Parser<I, $output, E>),+ |
779 | { |
780 | #[inline(always)] |
781 | fn parse_next(&mut self, i: I) -> IResult<I, ($($output),+,), E> { |
782 | let ($(ref mut $parser),+,) = *self; |
783 | |
784 | $(let(i, $output) = $parser.parse_next(i)?;)+ |
785 | |
786 | Ok((i, ($($output),+,))) |
787 | } |
788 | } |
789 | ) |
790 | } |
791 | |
792 | macro_rules! impl_parser_for_tuples { |
793 | ($parser1:ident $output1:ident, $($parser:ident $output:ident),+) => { |
794 | impl_parser_for_tuples!(__impl $parser1 $output1; $($parser $output),+); |
795 | }; |
796 | (__impl $($parser:ident $output:ident),+; $parser1:ident $output1:ident $(,$parser2:ident $output2:ident)*) => { |
797 | impl_parser_for_tuple!($($parser $output),+); |
798 | impl_parser_for_tuples!(__impl $($parser $output),+, $parser1 $output1; $($parser2 $output2),*); |
799 | }; |
800 | (__impl $($parser:ident $output:ident),+;) => { |
801 | impl_parser_for_tuple!($($parser $output),+); |
802 | } |
803 | } |
804 | |
805 | impl_parser_for_tuples!( |
806 | P1 O1, |
807 | P2 O2, |
808 | P3 O3, |
809 | P4 O4, |
810 | P5 O5, |
811 | P6 O6, |
812 | P7 O7, |
813 | P8 O8, |
814 | P9 O9, |
815 | P10 O10, |
816 | P11 O11, |
817 | P12 O12, |
818 | P13 O13, |
819 | P14 O14, |
820 | P15 O15, |
821 | P16 O16, |
822 | P17 O17, |
823 | P18 O18, |
824 | P19 O19, |
825 | P20 O20, |
826 | P21 O21 |
827 | ); |
828 | |
829 | #[cfg (feature = "alloc" )] |
830 | use alloc::boxed::Box; |
831 | |
832 | #[cfg (feature = "alloc" )] |
833 | impl<'a, I, O, E> Parser<I, O, E> for Box<dyn Parser<I, O, E> + 'a> { |
834 | #[inline (always)] |
835 | fn parse_next(&mut self, input: I) -> IResult<I, O, E> { |
836 | (**self).parse_next(input) |
837 | } |
838 | } |
839 | |
840 | #[cfg (test)] |
841 | mod tests { |
842 | use super::*; |
843 | use crate::binary::be_u16; |
844 | use crate::error::ErrMode; |
845 | use crate::error::Error; |
846 | use crate::error::ErrorKind; |
847 | use crate::error::Needed; |
848 | use crate::token::take; |
849 | use crate::Partial; |
850 | |
851 | #[doc (hidden)] |
852 | #[macro_export ] |
853 | macro_rules! assert_size ( |
854 | ($t:ty, $sz:expr) => ( |
855 | assert!($crate::lib::std::mem::size_of::<$t>() <= $sz, "{} <= {} failed" , $crate::lib::std::mem::size_of::<$t>(), $sz); |
856 | ); |
857 | ); |
858 | |
859 | #[test ] |
860 | #[cfg (target_pointer_width = "64" )] |
861 | fn size_test() { |
862 | assert_size!(IResult<&[u8], &[u8], (&[u8], u32)>, 40); |
863 | assert_size!(IResult<&str, &str, u32>, 40); |
864 | assert_size!(Needed, 8); |
865 | assert_size!(ErrMode<u32>, 16); |
866 | assert_size!(ErrorKind, 1); |
867 | } |
868 | |
869 | #[test ] |
870 | fn err_map_test() { |
871 | let e = ErrMode::Backtrack(1); |
872 | assert_eq!(e.map(|v| v + 1), ErrMode::Backtrack(2)); |
873 | } |
874 | |
875 | #[test ] |
876 | fn single_element_tuples() { |
877 | use crate::ascii::alpha1; |
878 | use crate::error::ErrorKind; |
879 | |
880 | let mut parser = (alpha1,); |
881 | assert_eq!(parser.parse_next("abc123def" ), Ok(("123def" , ("abc" ,)))); |
882 | assert_eq!( |
883 | parser.parse_next("123def" ), |
884 | Err(ErrMode::Backtrack(Error { |
885 | input: "123def" , |
886 | kind: ErrorKind::Slice |
887 | })) |
888 | ); |
889 | } |
890 | |
891 | #[test ] |
892 | fn tuple_test() { |
893 | #[allow (clippy::type_complexity)] |
894 | fn tuple_3(i: Partial<&[u8]>) -> IResult<Partial<&[u8]>, (u16, &[u8], &[u8])> { |
895 | (be_u16, take(3u8), "fg" ).parse_next(i) |
896 | } |
897 | |
898 | assert_eq!( |
899 | tuple_3(Partial::new(&b"abcdefgh" [..])), |
900 | Ok(( |
901 | Partial::new(&b"h" [..]), |
902 | (0x6162u16, &b"cde" [..], &b"fg" [..]) |
903 | )) |
904 | ); |
905 | assert_eq!( |
906 | tuple_3(Partial::new(&b"abcd" [..])), |
907 | Err(ErrMode::Incomplete(Needed::new(1))) |
908 | ); |
909 | assert_eq!( |
910 | tuple_3(Partial::new(&b"abcde" [..])), |
911 | Err(ErrMode::Incomplete(Needed::new(2))) |
912 | ); |
913 | assert_eq!( |
914 | tuple_3(Partial::new(&b"abcdejk" [..])), |
915 | Err(ErrMode::Backtrack(error_position!( |
916 | Partial::new(&b"jk" [..]), |
917 | ErrorKind::Tag |
918 | ))) |
919 | ); |
920 | } |
921 | |
922 | #[test ] |
923 | fn unit_type() { |
924 | fn parser(i: &str) -> IResult<&str, ()> { |
925 | ().parse_next(i) |
926 | } |
927 | assert_eq!(parser.parse_next("abxsbsh" ), Ok(("abxsbsh" , ()))); |
928 | assert_eq!(parser.parse_next("sdfjakdsas" ), Ok(("sdfjakdsas" , ()))); |
929 | assert_eq!(parser.parse_next("" ), Ok(("" , ()))); |
930 | } |
931 | } |
932 | |