1 use crate::combinator::trace;
2 use crate::error::{ErrMode, ErrorKind, Needed, ParserError};
3 use crate::stream::Stream;
4 use crate::*;
5
6 /// Deprecated, replaced with [`token::rest`]
7 #[deprecated(since = "0.6.23", note = "replaced with `token::rest`")]
8 #[inline]
rest<Input, Error>(input: &mut Input) -> PResult<<Input as Stream>::Slice, Error> where Input: Stream, Error: ParserError<Input>,9 pub fn rest<Input, Error>(input: &mut Input) -> PResult<<Input as Stream>::Slice, Error>
10 where
11 Input: Stream,
12 Error: ParserError<Input>,
13 {
14 crate::token::rest(input)
15 }
16
17 /// Deprecated, replaced with [`token::rest_len`]
18 #[deprecated(since = "0.6.23", note = "replaced with `token::rest_len`")]
19 #[inline]
rest_len<Input, Error>(input: &mut Input) -> PResult<usize, Error> where Input: Stream, Error: ParserError<Input>,20 pub fn rest_len<Input, Error>(input: &mut Input) -> PResult<usize, Error>
21 where
22 Input: Stream,
23 Error: ParserError<Input>,
24 {
25 crate::token::rest_len(input)
26 }
27
28 /// Apply a [`Parser`], producing `None` on [`ErrMode::Backtrack`].
29 ///
30 /// To chain an error up, see [`cut_err`].
31 ///
32 /// # Example
33 ///
34 /// ```rust
35 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError};
36 /// # use winnow::prelude::*;
37 /// use winnow::combinator::opt;
38 /// use winnow::ascii::alpha1;
39 /// # fn main() {
40 ///
41 /// fn parser(i: &str) -> IResult<&str, Option<&str>> {
42 /// opt(alpha1).parse_peek(i)
43 /// }
44 ///
45 /// assert_eq!(parser("abcd;"), Ok((";", Some("abcd"))));
46 /// assert_eq!(parser("123;"), Ok(("123;", None)));
47 /// # }
48 /// ```
opt<Input: Stream, Output, Error, ParseNext>( mut parser: ParseNext, ) -> impl Parser<Input, Option<Output>, Error> where ParseNext: Parser<Input, Output, Error>, Error: ParserError<Input>,49 pub fn opt<Input: Stream, Output, Error, ParseNext>(
50 mut parser: ParseNext,
51 ) -> impl Parser<Input, Option<Output>, Error>
52 where
53 ParseNext: Parser<Input, Output, Error>,
54 Error: ParserError<Input>,
55 {
56 trace("opt", move |input: &mut Input| {
57 let start = input.checkpoint();
58 match parser.parse_next(input) {
59 Ok(o) => Ok(Some(o)),
60 Err(ErrMode::Backtrack(_)) => {
61 input.reset(&start);
62 Ok(None)
63 }
64 Err(e) => Err(e),
65 }
66 })
67 }
68
69 /// Calls the parser if the condition is met.
70 ///
71 /// # Example
72 ///
73 /// ```rust
74 /// # use winnow::{error::ErrMode, error::{InputError, ErrorKind}, IResult};
75 /// # use winnow::prelude::*;
76 /// use winnow::combinator::cond;
77 /// use winnow::ascii::alpha1;
78 /// # fn main() {
79 ///
80 /// fn parser(b: bool, i: &str) -> IResult<&str, Option<&str>> {
81 /// cond(b, alpha1).parse_peek(i)
82 /// }
83 ///
84 /// assert_eq!(parser(true, "abcd;"), Ok((";", Some("abcd"))));
85 /// assert_eq!(parser(false, "abcd;"), Ok(("abcd;", None)));
86 /// assert_eq!(parser(true, "123;"), Err(ErrMode::Backtrack(InputError::new("123;", ErrorKind::Slice))));
87 /// assert_eq!(parser(false, "123;"), Ok(("123;", None)));
88 /// # }
89 /// ```
cond<Input, Output, Error, ParseNext>( cond: bool, mut parser: ParseNext, ) -> impl Parser<Input, Option<Output>, Error> where Input: Stream, ParseNext: Parser<Input, Output, Error>, Error: ParserError<Input>,90 pub fn cond<Input, Output, Error, ParseNext>(
91 cond: bool,
92 mut parser: ParseNext,
93 ) -> impl Parser<Input, Option<Output>, Error>
94 where
95 Input: Stream,
96 ParseNext: Parser<Input, Output, Error>,
97 Error: ParserError<Input>,
98 {
99 trace("cond", move |input: &mut Input| {
100 if cond {
101 parser.parse_next(input).map(Some)
102 } else {
103 Ok(None)
104 }
105 })
106 }
107
108 /// Apply the parser without advancing the input.
109 ///
110 /// To lookahead and only advance on success, see [`opt`].
111 ///
112 /// # Example
113 ///
114 /// ```rust
115 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, IResult};
116 /// # use winnow::prelude::*;
117 /// use winnow::combinator::peek;
118 /// use winnow::ascii::alpha1;
119 /// # fn main() {
120 ///
121 /// let mut parser = peek(alpha1);
122 ///
123 /// assert_eq!(parser.parse_peek("abcd;"), Ok(("abcd;", "abcd")));
124 /// assert_eq!(parser.parse_peek("123;"), Err(ErrMode::Backtrack(InputError::new("123;", ErrorKind::Slice))));
125 /// # }
126 /// ```
127 #[doc(alias = "look_ahead")]
128 #[doc(alias = "rewind")]
peek<Input, Output, Error, ParseNext>( mut parser: ParseNext, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, ParseNext: Parser<Input, Output, Error>,129 pub fn peek<Input, Output, Error, ParseNext>(
130 mut parser: ParseNext,
131 ) -> impl Parser<Input, Output, Error>
132 where
133 Input: Stream,
134 Error: ParserError<Input>,
135 ParseNext: Parser<Input, Output, Error>,
136 {
137 trace("peek", move |input: &mut Input| {
138 let start = input.checkpoint();
139 let res = parser.parse_next(input);
140 input.reset(&start);
141 res
142 })
143 }
144
145 /// Match the end of the [`Stream`]
146 ///
147 /// Otherwise, it will error.
148 ///
149 /// # Effective Signature
150 ///
151 /// Assuming you are parsing a `&str` [Stream]:
152 /// ```rust
153 /// # use winnow::prelude::*;;
154 /// pub fn eof<'i>(input: &mut &'i str) -> PResult<&'i str>
155 /// # {
156 /// # winnow::combinator::eof.parse_next(input)
157 /// # }
158 /// ```
159 ///
160 /// # Example
161 ///
162 /// ```rust
163 /// # use std::str;
164 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError};
165 /// # use winnow::combinator::eof;
166 /// # use winnow::prelude::*;
167 ///
168 /// let mut parser = eof;
169 /// assert_eq!(parser.parse_peek("abc"), Err(ErrMode::Backtrack(InputError::new("abc", ErrorKind::Eof))));
170 /// assert_eq!(parser.parse_peek(""), Ok(("", "")));
171 /// ```
172 #[doc(alias = "end")]
173 #[doc(alias = "eoi")]
eof<Input, Error>(input: &mut Input) -> PResult<<Input as Stream>::Slice, Error> where Input: Stream, Error: ParserError<Input>,174 pub fn eof<Input, Error>(input: &mut Input) -> PResult<<Input as Stream>::Slice, Error>
175 where
176 Input: Stream,
177 Error: ParserError<Input>,
178 {
179 trace("eof", move |input: &mut Input| {
180 if input.eof_offset() == 0 {
181 Ok(input.next_slice(0))
182 } else {
183 Err(ErrMode::from_error_kind(input, ErrorKind::Eof))
184 }
185 })
186 .parse_next(input)
187 }
188
189 /// Succeeds if the child parser returns an error.
190 ///
191 /// <div class="warning">
192 ///
193 /// **Note:** This does not advance the [`Stream`]
194 ///
195 /// </div>
196 ///
197 /// # Example
198 ///
199 /// ```rust
200 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, IResult};
201 /// # use winnow::prelude::*;
202 /// use winnow::combinator::not;
203 /// use winnow::ascii::alpha1;
204 /// # fn main() {
205 ///
206 /// let mut parser = not(alpha1);
207 ///
208 /// assert_eq!(parser.parse_peek("123"), Ok(("123", ())));
209 /// assert_eq!(parser.parse_peek("abcd"), Err(ErrMode::Backtrack(InputError::new("abcd", ErrorKind::Not))));
210 /// # }
211 /// ```
not<Input, Output, Error, ParseNext>(mut parser: ParseNext) -> impl Parser<Input, (), Error> where Input: Stream, Error: ParserError<Input>, ParseNext: Parser<Input, Output, Error>,212 pub fn not<Input, Output, Error, ParseNext>(mut parser: ParseNext) -> impl Parser<Input, (), Error>
213 where
214 Input: Stream,
215 Error: ParserError<Input>,
216 ParseNext: Parser<Input, Output, Error>,
217 {
218 trace("not", move |input: &mut Input| {
219 let start = input.checkpoint();
220 let res = parser.parse_next(input);
221 input.reset(&start);
222 match res {
223 Ok(_) => Err(ErrMode::from_error_kind(input, ErrorKind::Not)),
224 Err(ErrMode::Backtrack(_)) => Ok(()),
225 Err(e) => Err(e),
226 }
227 })
228 }
229
230 /// Transforms an [`ErrMode::Backtrack`] (recoverable) to [`ErrMode::Cut`] (unrecoverable)
231 ///
232 /// This commits the parse result, preventing alternative branch paths like with
233 /// [`winnow::combinator::alt`][crate::combinator::alt].
234 ///
235 /// See the [tutorial][crate::_tutorial::chapter_7] for more details.
236 ///
237 /// # Example
238 ///
239 /// Without `cut_err`:
240 /// ```rust
241 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError};
242 /// # use winnow::token::one_of;
243 /// # use winnow::token::rest;
244 /// # use winnow::ascii::digit1;
245 /// # use winnow::combinator::alt;
246 /// # use winnow::combinator::preceded;
247 /// # use winnow::prelude::*;
248 /// # fn main() {
249 ///
250 /// fn parser(input: &str) -> IResult<&str, &str> {
251 /// alt((
252 /// preceded(one_of(['+', '-']), digit1),
253 /// rest
254 /// )).parse_peek(input)
255 /// }
256 ///
257 /// assert_eq!(parser("+10 ab"), Ok((" ab", "10")));
258 /// assert_eq!(parser("ab"), Ok(("", "ab")));
259 /// assert_eq!(parser("+"), Ok(("", "+")));
260 /// # }
261 /// ```
262 ///
263 /// With `cut_err`:
264 /// ```rust
265 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError};
266 /// # use winnow::prelude::*;
267 /// # use winnow::token::one_of;
268 /// # use winnow::token::rest;
269 /// # use winnow::ascii::digit1;
270 /// # use winnow::combinator::alt;
271 /// # use winnow::combinator::preceded;
272 /// use winnow::combinator::cut_err;
273 /// # fn main() {
274 ///
275 /// fn parser(input: &str) -> IResult<&str, &str> {
276 /// alt((
277 /// preceded(one_of(['+', '-']), cut_err(digit1)),
278 /// rest
279 /// )).parse_peek(input)
280 /// }
281 ///
282 /// assert_eq!(parser("+10 ab"), Ok((" ab", "10")));
283 /// assert_eq!(parser("ab"), Ok(("", "ab")));
284 /// assert_eq!(parser("+"), Err(ErrMode::Cut(InputError::new("", ErrorKind::Slice ))));
285 /// # }
286 /// ```
cut_err<Input, Output, Error, ParseNext>( mut parser: ParseNext, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, ParseNext: Parser<Input, Output, Error>,287 pub fn cut_err<Input, Output, Error, ParseNext>(
288 mut parser: ParseNext,
289 ) -> impl Parser<Input, Output, Error>
290 where
291 Input: Stream,
292 Error: ParserError<Input>,
293 ParseNext: Parser<Input, Output, Error>,
294 {
295 trace("cut_err", move |input: &mut Input| {
296 parser.parse_next(input).map_err(|e| e.cut())
297 })
298 }
299
300 /// Transforms an [`ErrMode::Cut`] (unrecoverable) to [`ErrMode::Backtrack`] (recoverable)
301 ///
302 /// This attempts the parse, allowing other parsers to be tried on failure, like with
303 /// [`winnow::combinator::alt`][crate::combinator::alt].
backtrack_err<Input, Output, Error, ParseNext>( mut parser: ParseNext, ) -> impl Parser<Input, Output, Error> where Input: Stream, Error: ParserError<Input>, ParseNext: Parser<Input, Output, Error>,304 pub fn backtrack_err<Input, Output, Error, ParseNext>(
305 mut parser: ParseNext,
306 ) -> impl Parser<Input, Output, Error>
307 where
308 Input: Stream,
309 Error: ParserError<Input>,
310 ParseNext: Parser<Input, Output, Error>,
311 {
312 trace("backtrack_err", move |input: &mut Input| {
313 parser.parse_next(input).map_err(|e| e.backtrack())
314 })
315 }
316
317 /// A placeholder for a not-yet-implemented [`Parser`]
318 ///
319 /// This is analogous to the [`todo!`] macro and helps with prototyping.
320 ///
321 /// # Panic
322 ///
323 /// This will panic when parsing
324 ///
325 /// # Example
326 ///
327 /// ```rust
328 /// # use winnow::prelude::*;
329 /// # use winnow::combinator::todo;
330 ///
331 /// fn parser(input: &mut &str) -> PResult<u64> {
332 /// todo(input)
333 /// }
334 /// ```
335 #[track_caller]
todo<Input, Output, Error>(input: &mut Input) -> PResult<Output, Error> where Input: Stream,336 pub fn todo<Input, Output, Error>(input: &mut Input) -> PResult<Output, Error>
337 where
338 Input: Stream,
339 {
340 #![allow(clippy::todo)]
341 trace("todo", move |_input: &mut Input| {
342 todo!("unimplemented parse")
343 })
344 .parse_next(input)
345 }
346
347 /// Repeats the embedded parser, lazily returning the results
348 ///
349 /// Call the iterator's [`ParserIterator::finish`] method to get the remaining input if successful,
350 /// or the error value if we encountered an error.
351 ///
352 /// On [`ErrMode::Backtrack`], iteration will stop. To instead chain an error up, see [`cut_err`].
353 ///
354 /// # Example
355 ///
356 /// ```rust
357 /// use winnow::{combinator::iterator, IResult, ascii::alpha1, combinator::terminated};
358 /// use std::collections::HashMap;
359 ///
360 /// let data = "abc|defg|hijkl|mnopqr|123";
361 /// let mut it = iterator(data, terminated(alpha1, "|"));
362 ///
363 /// let parsed = it.map(|v| (v, v.len())).collect::<HashMap<_,_>>();
364 /// let res: IResult<_,_> = it.finish();
365 ///
366 /// assert_eq!(parsed, [("abc", 3usize), ("defg", 4), ("hijkl", 5), ("mnopqr", 6)].iter().cloned().collect());
367 /// assert_eq!(res, Ok(("123", ())));
368 /// ```
iterator<Input, Output, Error, ParseNext>( input: Input, parser: ParseNext, ) -> ParserIterator<ParseNext, Input, Output, Error> where ParseNext: Parser<Input, Output, Error>, Input: Stream, Error: ParserError<Input>,369 pub fn iterator<Input, Output, Error, ParseNext>(
370 input: Input,
371 parser: ParseNext,
372 ) -> ParserIterator<ParseNext, Input, Output, Error>
373 where
374 ParseNext: Parser<Input, Output, Error>,
375 Input: Stream,
376 Error: ParserError<Input>,
377 {
378 ParserIterator {
379 parser,
380 input,
381 state: Some(State::Running),
382 o: Default::default(),
383 }
384 }
385
386 /// Main structure associated to [`iterator`].
387 pub struct ParserIterator<F, I, O, E>
388 where
389 F: Parser<I, O, E>,
390 I: Stream,
391 {
392 parser: F,
393 input: I,
394 state: Option<State<E>>,
395 o: core::marker::PhantomData<O>,
396 }
397
398 impl<F, I, O, E> ParserIterator<F, I, O, E>
399 where
400 F: Parser<I, O, E>,
401 I: Stream,
402 {
403 /// Returns the remaining input if parsing was successful, or the error if we encountered an error.
finish(mut self) -> PResult<(I, ()), E>404 pub fn finish(mut self) -> PResult<(I, ()), E> {
405 match self.state.take().unwrap() {
406 State::Running | State::Done => Ok((self.input, ())),
407 State::Failure(e) => Err(ErrMode::Cut(e)),
408 State::Incomplete(i) => Err(ErrMode::Incomplete(i)),
409 }
410 }
411 }
412
413 impl<F, I, O, E> core::iter::Iterator for &mut ParserIterator<F, I, O, E>
414 where
415 F: Parser<I, O, E>,
416 I: Stream,
417 {
418 type Item = O;
419
next(&mut self) -> Option<Self::Item>420 fn next(&mut self) -> Option<Self::Item> {
421 if let State::Running = self.state.take().unwrap() {
422 let start = self.input.checkpoint();
423
424 match self.parser.parse_next(&mut self.input) {
425 Ok(o) => {
426 self.state = Some(State::Running);
427 Some(o)
428 }
429 Err(ErrMode::Backtrack(_)) => {
430 self.input.reset(&start);
431 self.state = Some(State::Done);
432 None
433 }
434 Err(ErrMode::Cut(e)) => {
435 self.state = Some(State::Failure(e));
436 None
437 }
438 Err(ErrMode::Incomplete(i)) => {
439 self.state = Some(State::Incomplete(i));
440 None
441 }
442 }
443 } else {
444 None
445 }
446 }
447 }
448
449 enum State<E> {
450 Running,
451 Done,
452 Failure(E),
453 Incomplete(Needed),
454 }
455
456 /// Succeed, consuming no input
457 ///
458 /// For example, it can be used as the last alternative in `alt` to
459 /// specify the default case.
460 ///
461 /// Useful with:
462 /// - [`Parser::value`]
463 /// - [`Parser::default_value`]
464 /// - [`Parser::map`]
465 ///
466 /// <div class="warning">
467 ///
468 /// **Note:** This never advances the [`Stream`]
469 ///
470 /// </div>
471 ///
472 /// # Example
473 ///
474 /// ```rust
475 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError};
476 /// # use winnow::prelude::*;
477 /// use winnow::combinator::alt;
478 /// use winnow::combinator::empty;
479 ///
480 /// fn sign(input: &str) -> IResult<&str, isize> {
481 /// alt((
482 /// '-'.value(-1),
483 /// '+'.value(1),
484 /// empty.value(1)
485 /// )).parse_peek(input)
486 /// }
487 /// assert_eq!(sign("+10"), Ok(("10", 1)));
488 /// assert_eq!(sign("-10"), Ok(("10", -1)));
489 /// assert_eq!(sign("10"), Ok(("10", 1)));
490 /// ```
491 #[doc(alias = "value")]
492 #[doc(alias = "success")]
493 #[inline]
empty<Input, Error>(_input: &mut Input) -> PResult<(), Error> where Input: Stream, Error: ParserError<Input>,494 pub fn empty<Input, Error>(_input: &mut Input) -> PResult<(), Error>
495 where
496 Input: Stream,
497 Error: ParserError<Input>,
498 {
499 Ok(())
500 }
501
502 /// A parser which always fails.
503 ///
504 /// For example, it can be used as the last alternative in `alt` to
505 /// control the error message given.
506 ///
507 /// # Example
508 ///
509 /// ```rust
510 /// # use winnow::{error::ErrMode, error::ErrorKind, error::InputError, IResult};
511 /// # use winnow::prelude::*;
512 /// use winnow::combinator::fail;
513 ///
514 /// let s = "string";
515 /// assert_eq!(fail::<_, &str, _>.parse_peek(s), Err(ErrMode::Backtrack(InputError::new(s, ErrorKind::Fail))));
516 /// ```
517 #[doc(alias = "unexpected")]
518 #[inline]
fail<Input, Output, Error>(i: &mut Input) -> PResult<Output, Error> where Input: Stream, Error: ParserError<Input>,519 pub fn fail<Input, Output, Error>(i: &mut Input) -> PResult<Output, Error>
520 where
521 Input: Stream,
522 Error: ParserError<Input>,
523 {
524 trace("fail", |i: &mut Input| {
525 Err(ErrMode::from_error_kind(i, ErrorKind::Fail))
526 })
527 .parse_next(i)
528 }
529