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