Module winnow::_tutorial::chapter_6

source ·
Available on crate feature unstable-doc only.
Expand description

§Chapter 6: Integrating the Parser

So far, we’ve highlighted how to incrementally parse, but how do we bring this all together into our application?

Parsers we’ve been working with look like:

use winnow::PResult;

pub fn parser<'s>(input: &mut &'s str) -> PResult<&'s str> {
    // ...
}
  1. We have to decide what to do about the “remainder” of the input.
  2. The PResult is not compatible with the rest of the Rust ecosystem. Normally, Rust applications want errors that are std::error::Error + Send + Sync + 'static meaning:
    • They implement the std::error::Error trait
    • They can be sent across threads
    • They are safe to be referenced across threads
    • They do not borrow

winnow provides Parser::parse to help with this:

use winnow::Parser;

#[derive(Debug, PartialEq, Eq)]
pub struct Hex(usize);

impl std::str::FromStr for Hex {
    type Err = String;

    fn from_str(input: &str) -> Result<Self, Self::Err> {
        parse_digits
            .map(Hex)
            .parse(input)
            .map_err(|e| e.to_string())
    }
}

// ...

fn main() {
    let input = "0x1a2b";
    assert_eq!(input.parse::<Hex>().unwrap(), Hex(0x1a2b));

    let input = "0x1a2b Hello";
    assert!(input.parse::<Hex>().is_err());
    let input = "ghiHello";
    assert!(input.parse::<Hex>().is_err());
}

Re-exports§