Trait Parser

trait Parser<I, O, E>

Core trait for parsing

The simplest way to implement a Parser is with a function

use winnow::prelude::*;

fn empty(input: &mut &str) -> ModalResult<()> {
    let output = ();
    Ok(output)
}

let (input, output) = empty.parse_peek("Hello").unwrap();
assert_eq!(input, "Hello");  // We didn't consume any input

which can be made stateful by returning a function

use winnow::prelude::*;

fn empty<O: Clone>(output: O) -> impl FnMut(&mut &str) -> ModalResult<O> {
    move |input: &mut &str| {
        let output = output.clone();
        Ok(output)
    }
}

let (input, output) = empty("World").parse_peek("Hello").unwrap();
assert_eq!(input, "Hello");  // We didn't consume any input
assert_eq!(output, "World");

Additionally, some basic types implement Parser as well, including

Required Methods

fn parse_next(self: &mut Self, input: &mut I) -> Result<O, E>

Take tokens from the Stream, turning it into the output

This includes advancing the Stream to the next location.

On error, input will be left pointing at the error location.

Provided Methods

fn parse(self: &mut Self, input: I) -> Result<O, ParseError<I, <E as ParserError<I>>::Inner>>
where
    Self: core::marker::Sized,
    I: Stream + StreamIsPartial,
    E: ParserError<I>,
    <E as ParserError<I>>::Inner: ParserError<I>

Parse all of input, generating O from it

fn parse_peek(self: &mut Self, input: I) -> Result<(I, O), E>

Take tokens from the Stream, turning it into the output

This returns a copy of the Stream advanced to the next location.

Generally, prefer Parser::parse_next. This is primarily intended for:

  • Migrating from older versions / nom
  • Testing Parsers

For look-ahead parsing, see instead [peek][crate::combinator::peek].

fn by_ref(self: &mut Self) -> impls::ByRef<'_, Self, I, O, E>
where
    Self: core::marker::Sized

Treat &mut Self as a parser

This helps when needing to move a Parser when all you have is a &mut Parser.

Example

Because parsers are FnMut, they can be called multiple times. This prevents moving f into [length_take][crate::binary::length_take] and g into [Parser::complete_err]:

# use winnow::prelude::*;
# use winnow::Parser;
# use winnow::error::ParserError;
# use winnow::binary::length_take;
pub fn length_value<'i, O, E: ParserError<&'i [u8]>>(
    mut f: impl Parser<&'i [u8], usize, E>,
    mut g: impl Parser<&'i [u8], O, E>
) -> impl Parser<&'i [u8], O, E> {
  move |i: &mut &'i [u8]| {
    let mut data = length_take(f).parse_next(i)?;
    let o = g.complete_err().parse_next(&mut data)?;
    Ok(o)
  }
}

By adding by_ref, we can make this work:

# use winnow::prelude::*;
# use winnow::Parser;
# use winnow::error::ParserError;
# use winnow::binary::length_take;
pub fn length_value<'i, O, E: ParserError<&'i [u8]>>(
    mut f: impl Parser<&'i [u8], usize, E>,
    mut g: impl Parser<&'i [u8], O, E>
) -> impl Parser<&'i [u8], O, E> {
  move |i: &mut &'i [u8]| {
    let mut data = length_take(f.by_ref()).parse_next(i)?;
    let o = g.by_ref().complete_err().parse_next(&mut data)?;
    Ok(o)
  }
}
fn value<O2>(self: Self, val: O2) -> impls::Value<Self, I, O, O2, E>
where
    Self: core::marker::Sized,
    O2: Clone

Produce the provided value

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::alpha1;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<i32> {
    alpha1.value(1234).parse_next(input)
}

assert_eq!(parser.parse_peek("abcd"), Ok(("", 1234)));
assert!(parser.parse_peek("123abcd;").is_err());
# }
fn default_value<O2>(self: Self) -> impls::DefaultValue<Self, I, O, O2, E>
where
    Self: core::marker::Sized,
    O2: core::default::Default

Produce a type's default value

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::alpha1;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<u32> {
    alpha1.default_value().parse_next(input)
}

assert_eq!(parser.parse_peek("abcd"), Ok(("", 0)));
assert!(parser.parse_peek("123abcd;").is_err());
# }
fn void(self: Self) -> impls::Void<Self, I, O, E>
where
    Self: core::marker::Sized

Discards the output of the Parser

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::alpha1;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<()> {
    alpha1.void().parse_next(input)
}

assert_eq!(parser.parse_peek("abcd"), Ok(("", ())));
assert!(parser.parse_peek("123abcd;").is_err());
# }
fn output_into<O2>(self: Self) -> impls::OutputInto<Self, I, O, O2, E>
where
    Self: core::marker::Sized,
    O: Into<O2>

Convert the parser's output to another type using std::convert::From

Example

# use winnow::prelude::*;
# use winnow::error::ContextError;
use winnow::ascii::alpha1;
# fn main() {

fn parser1<'s>(i: &mut &'s str) -> ModalResult<&'s str> {
  alpha1(i)
}

let mut parser2 = parser1.output_into();

// the parser converts the &str output of the child parser into a Vec<u8>
let bytes: ModalResult<(_, Vec<u8>), _> = parser2.parse_peek("abcd");
assert_eq!(bytes, Ok(("", vec![97, 98, 99, 100])));
# }
fn take(self: Self) -> impls::Take<Self, I, O, E>
where
    Self: core::marker::Sized,
    I: Stream

Produce the consumed input as produced value.

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::{alpha1};
use winnow::combinator::separated_pair;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
    separated_pair(alpha1, ',', alpha1).take().parse_next(input)
}

assert_eq!(parser.parse_peek("abcd,efgh"), Ok(("", "abcd,efgh")));
assert!(parser.parse_peek("abcd;").is_err());
# }
fn with_taken(self: Self) -> impls::WithTaken<Self, I, O, E>
where
    Self: core::marker::Sized,
    I: Stream

Produce the consumed input with the output

Functions similarly to [take][Parser::take] except it returns the parser output as well.

This can be useful especially in cases where the output is not the same type as the input, or the input is a user defined type.

Returned tuple is of the format (produced output, consumed input).

Example

# use winnow::prelude::*;
# use winnow::{error::ErrMode};
use winnow::ascii::{alpha1};
use winnow::token::literal;
use winnow::combinator::separated_pair;

fn parser<'i>(input: &mut &'i str) -> ModalResult<(bool, &'i str)> {
    separated_pair(alpha1, ',', alpha1).value(true).with_taken().parse_next(input)
}

assert_eq!(parser.parse_peek("abcd,efgh1"), Ok(("1", (true, "abcd,efgh"))));
assert!(parser.parse_peek("abcd;").is_err());
fn span(self: Self) -> impls::Span<Self, I, O, E>
where
    Self: core::marker::Sized,
    I: Stream + Location

Produce the location of the consumed input as produced value.

Example

# use winnow::prelude::*;
# use winnow::{error::ErrMode, stream::Stream};
# use std::ops::Range;
use winnow::stream::LocatingSlice;
use winnow::ascii::alpha1;
use winnow::combinator::separated_pair;

fn parser<'i>(input: &mut LocatingSlice<&'i str>) -> ModalResult<(Range<usize>, Range<usize>)> {
    separated_pair(alpha1.span(), ',', alpha1.span()).parse_next(input)
}

assert_eq!(parser.parse(LocatingSlice::new("abcd,efgh")), Ok((0..4, 5..9)));
assert!(parser.parse_peek(LocatingSlice::new("abcd;")).is_err());
fn with_span(self: Self) -> impls::WithSpan<Self, I, O, E>
where
    Self: core::marker::Sized,
    I: Stream + Location

Produce the location of consumed input with the output

Functions similarly to Parser::span except it returns the parser output as well.

This can be useful especially in cases where the output is not the same type as the input, or the input is a user defined type.

Returned tuple is of the format (produced output, consumed input).

Example

# use winnow::prelude::*;
# use winnow::{error::ErrMode, stream::Stream};
# use std::ops::Range;
use winnow::stream::LocatingSlice;
use winnow::ascii::alpha1;
use winnow::token::literal;
use winnow::combinator::separated_pair;

fn parser<'i>(input: &mut LocatingSlice<&'i str>) -> ModalResult<((usize, Range<usize>), (usize, Range<usize>))> {
    separated_pair(alpha1.value(1).with_span(), ',', alpha1.value(2).with_span()).parse_next(input)
}

assert_eq!(parser.parse(LocatingSlice::new("abcd,efgh")), Ok(((1, 0..4), (2, 5..9))));
assert!(parser.parse_peek(LocatingSlice::new("abcd;")).is_err());
fn map<G, O2>(self: Self, map: G) -> impls::Map<Self, G, I, O, O2, E>
where
    G: FnMut(O) -> O2,
    Self: core::marker::Sized

Maps a function over the output of a parser

Example

# use winnow::prelude::*;
# use winnow::{error::ErrMode, Parser};
# use winnow::ascii::digit1;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<usize> {
    digit1.map(|s: &str| s.len()).parse_next(input)
}

// the parser will count how many characters were returned by digit1
assert_eq!(parser.parse_peek("123456"), Ok(("", 6)));

// this will fail if digit1 fails
assert!(parser.parse_peek("abc").is_err());
# }
fn try_map<G, O2, E2>(self: Self, map: G) -> impls::TryMap<Self, G, I, O, O2, E, E2>
where
    Self: core::marker::Sized,
    G: FnMut(O) -> Result<O2, E2>,
    I: Stream,
    E: FromExternalError<I, E2> + ParserError<I>

Applies a function returning a Result over the output of a parser.

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::digit1;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<u8> {
    digit1.try_map(|s: &str| s.parse::<u8>()).parse_next(input)
}

// the parser will convert the result of digit1 to a number
assert_eq!(parser.parse_peek("123"), Ok(("", 123)));

// this will fail if digit1 fails
assert!(parser.parse_peek("abc").is_err());

// this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
assert!(parser.parse_peek("123456").is_err());
# }
fn verify_map<G, O2>(self: Self, map: G) -> impls::VerifyMap<Self, G, I, O, O2, E>
where
    Self: core::marker::Sized,
    G: FnMut(O) -> Option<O2>,
    I: Stream,
    E: ParserError<I>

Apply both Parser::verify and Parser::map.

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::digit1;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<u8> {
    digit1.verify_map(|s: &str| s.parse::<u8>().ok()).parse_next(input)
}

// the parser will convert the result of digit1 to a number
assert_eq!(parser.parse_peek("123"), Ok(("", 123)));

// this will fail if digit1 fails
assert!(parser.parse_peek("abc").is_err());

// this will fail if the mapped function fails (a `u8` is too small to hold `123456`)
assert!(parser.parse_peek("123456").is_err());
# }
fn flat_map<G, H, O2>(self: Self, map: G) -> impls::FlatMap<Self, G, H, I, O, O2, E>
where
    Self: core::marker::Sized,
    G: FnMut(O) -> H,
    H: Parser<I, O2, E>

Creates a parser from the output of this one

Example

# use winnow::{error::ErrMode, ModalResult, Parser};
use winnow::token::take;
use winnow::binary::u8;

fn length_take<'s>(input: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
    u8.flat_map(take).parse_next(input)
}

assert_eq!(length_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
assert!(length_take.parse_peek(&[4, 0, 1, 2][..]).is_err());

which is the same as

# use winnow::{error::ErrMode, ModalResult, Parser};
use winnow::token::take;
use winnow::binary::u8;

fn length_take<'s>(input: &mut &'s [u8]) -> ModalResult<&'s [u8]> {
    let length = u8.parse_next(input)?;
    let data = take(length).parse_next(input)?;
    Ok(data)
}

assert_eq!(length_take.parse_peek(&[2, 0, 1, 2][..]), Ok((&[2][..], &[0, 1][..])));
assert!(length_take.parse_peek(&[4, 0, 1, 2][..]).is_err());
fn and_then<G, O2>(self: Self, inner: G) -> impls::AndThen<Self, G, I, O, O2, E>
where
    Self: core::marker::Sized,
    G: Parser<O, O2, E>,
    O: StreamIsPartial,
    I: Stream

Applies a second parser over the output of the first one

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::prelude::*;
use winnow::ascii::digit1;
use winnow::token::take;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
    take(5u8).and_then(digit1).parse_next(input)
}

assert_eq!(parser.parse_peek("12345"), Ok(("", "12345")));
assert_eq!(parser.parse_peek("123ab"), Ok(("", "123")));
assert!(parser.parse_peek("123").is_err());
# }
fn parse_to<O2>(self: Self) -> impls::ParseTo<Self, I, O, O2, E>
where
    Self: core::marker::Sized,
    I: Stream,
    O: ParseSlice<O2>,
    E: ParserError<I>

Apply std::str::FromStr to the output of the parser

Example

# use winnow::prelude::*;
use winnow::{error::ErrMode, Parser};
use winnow::ascii::digit1;

fn parser<'s>(input: &mut &'s str) -> ModalResult<u64> {
    digit1.parse_to().parse_next(input)
}

// the parser will count how many characters were returned by digit1
assert_eq!(parser.parse_peek("123456"), Ok(("", 123456)));

// this will fail if digit1 fails
assert!(parser.parse_peek("abc").is_err());
fn verify<G, O2>(self: Self, filter: G) -> impls::Verify<Self, G, I, O, O2, E>
where
    Self: core::marker::Sized,
    G: FnMut(&O2) -> bool,
    I: Stream,
    O: crate::lib::std::borrow::Borrow<O2>,
    O2: ?Sized,
    E: ParserError<I>

Returns the output of the child parser if it satisfies a verification function.

The verification function takes as argument a reference to the output of the parser.

Example

# use winnow::{error::ErrMode, Parser};
# use winnow::ascii::alpha1;
# use winnow::prelude::*;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
    alpha1.verify(|s: &str| s.len() == 4).parse_next(input)
}

assert_eq!(parser.parse_peek("abcd"), Ok(("", "abcd")));
assert!(parser.parse_peek("abcde").is_err());
assert!(parser.parse_peek("123abcd;").is_err());
# }
fn context<C>(self: Self, context: C) -> impls::Context<Self, I, O, E, C>
where
    Self: core::marker::Sized,
    I: Stream,
    E: AddContext<I, C> + ParserError<I>,
    C: Clone + crate::lib::std::fmt::Debug

If parsing fails, add context to the error

This is used mainly to add user friendly information to errors when backtracking through a parse tree.

See also [tutorial][crate::_tutorial::chapter_7].

Example

# use winnow::prelude::*;
# use winnow::{error::ErrMode, Parser};
# use winnow::ascii::digit1;
# use winnow::error::StrContext;
# use winnow::error::StrContextValue;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
    digit1
      .context(StrContext::Expected(StrContextValue::Description("digit")))
      .parse_next(input)
}

assert_eq!(parser.parse_peek("123456"), Ok(("", "123456")));
assert!(parser.parse_peek("abc").is_err());
# }
fn context_with<F, C, FI>(self: Self, context: F) -> impls::ContextWith<Self, I, O, E, F, C, FI>
where
    Self: core::marker::Sized,
    I: Stream,
    E: AddContext<I, C> + ParserError<I>,
    F: Fn() -> FI + Clone,
    C: crate::lib::std::fmt::Debug,
    FI: Iterator<Item = C>

If parsing fails, dynamically add context to the error

This is used mainly to add user friendly information to errors when backtracking through a parse tree.

See also [tutorial][crate::_tutorial::chapter_7].

Example

# use winnow::prelude::*;
# use winnow::{error::ErrMode, Parser};
# use winnow::ascii::digit1;
# use winnow::error::StrContext;
# use winnow::error::StrContextValue;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> ModalResult<&'i str> {
    digit1
      .context_with(|| {
        "0123456789".chars().map(|c| StrContext::Expected(c.into()))
      })
      .parse_next(input)
}

assert_eq!(parser.parse_peek("123456"), Ok(("", "123456")));
assert!(parser.parse_peek("abc").is_err());
# }
fn map_err<G, E2>(self: Self, map: G) -> impls::MapErr<Self, G, I, O, E, E2>
where
    G: FnMut(E) -> E2,
    Self: core::marker::Sized

Maps a function over the error of a parser

Example

# use winnow::prelude::*;
# use winnow::Parser;
# use winnow::Result;
# use winnow::ascii::digit1;
# use winnow::error::StrContext;
# use winnow::error::AddContext;
# use winnow::error::ContextError;
# fn main() {

fn parser<'i>(input: &mut &'i str) -> Result<&'i str> {
    digit1.map_err(|mut e: ContextError| {
        e.extend("0123456789".chars().map(|c| StrContext::Expected(c.into())));
        e
    }).parse_next(input)
}

assert_eq!(parser.parse_peek("123456"), Ok(("", "123456")));
assert!(parser.parse_peek("abc").is_err());
# }
fn complete_err(self: Self) -> impls::CompleteErr<Self, I, O, E>
where
    Self: core::marker::Sized

Transforms [Incomplete][crate::error::ErrMode::Incomplete] into [Backtrack][crate::error::ErrMode::Backtrack]

Example

# use winnow::{error::ErrMode, error::InputError, stream::Partial, Parser};
# use winnow::token::take;
# use winnow::prelude::*;
# fn main() {

fn parser<'i>(input: &mut Partial<&'i str>) -> ModalResult<&'i str, InputError<Partial<&'i str>>> {
    take(5u8).complete_err().parse_next(input)
}

assert_eq!(parser.parse_peek(Partial::new("abcdefg")), Ok((Partial::new("fg"), "abcde")));
assert_eq!(parser.parse_peek(Partial::new("abcd")), Err(ErrMode::Backtrack(InputError::at(Partial::new("abcd")))));
# }
fn err_into<E2>(self: Self) -> impls::ErrInto<Self, I, O, E, E2>
where
    Self: core::marker::Sized,
    E: Into<E2>

Convert the parser's error to another type using std::convert::From

Implementors