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 compose more complex parsers from more simple 5 //! ones (using "combinators"). 6 //! 7 //! Let's discuss what a "parser" actually does. A parser takes an input and advances it until it 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 advanced to the end of 14 //! what was processed, pointing to what will be parsed next. 15 //! - If the parser failed, then there are multiple errors that could be returned. 16 //! We'll explore this further in [`chapter_7`]. 17 //! 18 //! ```text 19 //! ┌─► Ok(what matched the parser) 20 //! ┌────────┐ │ 21 //! my input───►│a parser├──►either──┤ 22 //! └────────┘ └─► Err(...) 23 //! ``` 24 //! 25 //! 26 //! To represent this model of the world, winnow uses the [`PResult<O>`] type. 27 //! The `Ok` variant has `output: O`; 28 //! whereas the `Err` variant stores an error. 29 //! 30 //! You can import that from: 31 //! 32 //! ```rust 33 //! use winnow::PResult; 34 //! ``` 35 //! 36 //! To combine parsers, we need a common way to refer to them which is where the [`Parser<I, O, E>`] 37 //! trait comes in with [`Parser::parse_next`] being the primary way to drive 38 //! parsing forward. 39 //! In [`chapter_6`], we'll cover how to integrate these into your application, particularly with 40 //! [`Parser::parse`]. 41 //! 42 //! You'll note that `I` and `O` are parameterized -- while most of the examples in this book 43 //! will be with `&str` (i.e. parsing a string); they do not have to be strings; nor do they 44 //! have to be the same type (consider the simple example where `I = &str`, and `O = u64` -- this 45 //! parses a string into an unsigned integer.) 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 input will be left where it started. 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 super::chapter_6; 82 use super::chapter_7; 83 use crate::PResult; 84 use crate::Parser; 85 86 pub use super::chapter_0 as previous; 87 pub use super::chapter_2 as next; 88 pub use crate::_tutorial as table_of_contents; 89