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