]> git.proxmox.com Git - rustc.git/blame - vendor/winnow/src/_tutorial/chapter_1.rs
New upstream version 1.76.0+dfsg1
[rustc.git] / vendor / winnow / src / _tutorial / chapter_1.rs
CommitLineData
49aad941
FG
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//!
add651ee 12//! Parsers do more than just return a binary "success"/"failure" code.
4b012472 13//! On success, the parser will return the processed data. The input will be left pointing to
add651ee 14//! data that still needs processing
49aad941
FG
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
4b012472
FG
20//! ┌─► Ok(what matched the parser)
21//! ┌─────────┐ │
22//! my input───►│my parser├──►either──┤
23//! └─────────┘ └─► Err(...)
49aad941
FG
24//! ```
25//!
26//!
add651ee
FG
27//! To represent this model of the world, winnow uses the [`PResult<O>`] type.
28//! The `Ok` variant has `output: O`;
49aad941
FG
29//! whereas the `Err` variant stores an error.
30//!
31//! You can import that from:
32//!
33//! ```rust
add651ee 34//! use winnow::PResult;
49aad941
FG
35//! ```
36//!
add651ee
FG
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//!
49aad941
FG
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//!
49aad941
FG
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
add651ee 52//! functions of the form `Fn(&mut I) -> PResult<O>`.
49aad941
FG
53//!
54//! This parser function should take in a `&str`:
55//!
4b012472 56//! - Since it is supposed to succeed, we know it will return the `Ok` variant.
49aad941
FG
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
add651ee 61//! use winnow::PResult;
49aad941
FG
62//! use winnow::Parser;
63//!
add651ee
FG
64//! pub fn do_nothing_parser<'s>(input: &mut &'s str) -> PResult<&'s str> {
65//! Ok("")
49aad941
FG
66//! }
67//!
68//! fn main() {
add651ee 69//! let mut input = "0x1a2b Hello";
49aad941 70//!
add651ee 71//! let output = do_nothing_parser.parse_next(&mut input).unwrap();
49aad941 72//! // Same as:
add651ee 73//! // let output = do_nothing_parser(&mut input).unwrap();
49aad941 74//!
add651ee 75//! assert_eq!(input, "0x1a2b Hello");
49aad941
FG
76//! assert_eq!(output, "");
77//! }
78//! ```
79
80#![allow(unused_imports)]
add651ee 81use crate::PResult;
49aad941
FG
82use crate::Parser;
83
84pub use super::chapter_0 as previous;
85pub use super::chapter_2 as next;
781aab86 86pub use crate::_tutorial as table_of_contents;