1 //! # Chapter 1: The Winnow Way 2 //! 3 //! First of all, we need to understand the way that winnow thinks about parsing. 4 //! As discussed in the introduction, winnow lets us build simple parsers, and 5 //! then combine them (using "combinators"). 6 //! 7 //! Let's discuss what a "parser" actually does. A parser takes an input and returns 8 //! a result, where: 9 //! - `Ok` indicates the parser successfully found what it was looking for; or 10 //! - `Err` indicates the parser could not find what it was looking for. 11 //! 12 //! Parsers do more than just return a binary "success"/"failure" code. 13 //! On success, the parser will return the processed data. The input will be left pointing to 14 //! data that still needs processing 15 //! 16 //! If the parser failed, then there are multiple errors that could be returned. 17 //! For simplicity, however, in the next chapters we will leave these unexplored. 18 //! 19 //! ```text 20 //! ┌─► Ok(what matched the parser) 21 //! ┌─────────┐ │ 22 //! my input───►│my parser├──►either──┤ 23 //! └─────────┘ └─► Err(...) 24 //! ``` 25 //! 26 //! 27 //! To represent this model of the world, winnow uses the [`PResult<O>`] type. 28 //! The `Ok` variant has `output: O`; 29 //! whereas the `Err` variant stores an error. 30 //! 31 //! You can import that from: 32 //! 33 //! ```rust 34 //! use winnow::PResult; 35 //! ``` 36 //! 37 //! To combine parsers, we need a common way to refer to them which is where the [`Parser<I, O, E>`] 38 //! trait comes in with [`Parser::parse_next`] being the primary way to drive 39 //! parsing forward. 40 //! 41 //! You'll note that `I` and `O` are parameterized -- while most of the examples in this book 42 //! will be with `&str` (i.e. parsing a string); they do not have to be strings; nor do they 43 //! have to be the same type (consider the simple example where `I = &str`, and `O = u64` -- this 44 //! parses a string into an unsigned integer.) 45 //! 46 //! 47 //! # Let's write our first parser! 48 //! 49 //! The simplest parser we can write is one which successfully does nothing. 50 //! 51 //! To make it easier to implement a [`Parser`], the trait is implemented for 52 //! functions of the form `Fn(&mut I) -> PResult<O>`. 53 //! 54 //! This parser function should take in a `&str`: 55 //! 56 //! - Since it is supposed to succeed, we know it will return the `Ok` variant. 57 //! - Since it does nothing to our input, the remaining input is the same as the input. 58 //! - Since it doesn't parse anything, it also should just return an empty string. 59 //! 60 //! ```rust 61 //! use winnow::PResult; 62 //! use winnow::Parser; 63 //! 64 //! pub fn do_nothing_parser<'s>(input: &mut &'s str) -> PResult<&'s str> { 65 //! Ok("") 66 //! } 67 //! 68 //! fn main() { 69 //! let mut input = "0x1a2b Hello"; 70 //! 71 //! let output = do_nothing_parser.parse_next(&mut input).unwrap(); 72 //! // Same as: 73 //! // let output = do_nothing_parser(&mut input).unwrap(); 74 //! 75 //! assert_eq!(input, "0x1a2b Hello"); 76 //! assert_eq!(output, ""); 77 //! } 78 //! ``` 79 80 #![allow(unused_imports)] 81 use crate::PResult; 82 use crate::Parser; 83 84 pub use super::chapter_0 as previous; 85 pub use super::chapter_2 as next; 86 pub use crate::_tutorial as table_of_contents; 87