1 //! # Custom [`Stream`] 2 //! 3 //! `winnow` is batteries included with support for 4 //! - Basic inputs like `&str`, newtypes with 5 //! - Improved debug output like [`Bytes`] 6 //! - [`Stateful`] for passing state through your parser, like tracking recursion 7 //! depth 8 //! - [`Located`] for looking up the absolute position of a token 9 //! 10 //! But that won't always cut it for your parser. For example, you might lex `&str` into 11 //! a series of tokens and then want to parse a `TokenStream`. 12 //! 13 //! ## Implementing a custom stream 14 //! 15 //! Let's assume we have an input type we'll call `MyStream`. 16 //! `MyStream` is a sequence of `MyItem` type. 17 //! 18 //! The goal is to define parsers with this signature: `&mut MyStream -> PResult<Output>`. 19 //! ```rust 20 //! # use winnow::prelude::*; 21 //! # use winnow::token::tag; 22 //! # type MyStream<'i> = &'i str; 23 //! # type Output<'i> = &'i str; 24 //! fn parser<'s>(i: &mut MyStream<'s>) -> PResult<Output<'s>> { 25 //! "test".parse_next(i) 26 //! } 27 //! ``` 28 //! 29 //! Here are the traits you may have to implement for `MyStream`: 30 //! 31 //! | trait | usage | 32 //! |---|---| 33 //! | [`Stream`] |Core trait for driving parsing| 34 //! | [`StreamIsPartial`] | Marks the input as being the complete buffer or a partial buffer for streaming input | 35 //! | [`AsBytes`] |Casts the input type to a byte slice| 36 //! | [`AsBStr`] |Casts the input type to a slice of ASCII / UTF-8-like bytes| 37 //! | [`Compare`] |Character comparison operations| 38 //! | [`FindSlice`] |Look for a substring in self| 39 //! | [`Location`] |Calculate location within initial input| 40 //! | [`Offset`] |Calculate the offset between slices| 41 //! 42 //! And for `MyItem`: 43 //! 44 //! | trait | usage | 45 //! |---|---| 46 //! | [`AsChar`] |Transforms common types to a char for basic token parsing| 47 //! | [`ContainsToken`] |Look for the token in the given set| 48 //! 49 //! And traits for `&[MyItem]`: 50 //! 51 //! | trait | usage | 52 //! |---|---| 53 //! | [`SliceLen`] |Calculate the input length| 54 //! | [`ParseSlice`] |Used to integrate `&str`'s `parse()` method| 55 //! 56 //! ## Implementing a custom token 57 //! 58 //! If you are parsing `&[Myitem]`, leaving just the `MyItem` traits. 59 //! 60 //! For example: 61 //! ```rust 62 #![doc = include_str!("../../examples/arithmetic/parser_lexer.rs")] 63 //! ``` 64 65 #[allow(unused_imports)] // Here for intra-dock links 66 use crate::stream::*; 67