winnow/_topic/stream.rs
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//! - [`LocatingSlice`] for looking up the absolute position of a token
9//!
10//! ## Implementing a custom token
11//!
12//! The first level of customization is parsing [`&[MyItem]`][Stream#impl-Stream-for-%26%5BT%5D]
13//! or [`TokenSlice<MyItem>`].
14//!
15//! The basic traits you may want for a custom token type are:
16//!
17//! | trait | usage |
18//! |---|---|
19//! | [`AsChar`] |Transforms common types to a char for basic token parsing|
20//! | [`ContainsToken`] |Look for the token in the given set|
21//!
22//! See also [`TokenSlice<MyItem>`], [lexing].
23//!
24//! ## Implementing a custom stream
25//!
26//! Let's assume we have an input type we'll call `MyStream`.
27//! `MyStream` is a sequence of `MyItem` tokens.
28//!
29//! The goal is to define parsers with this signature: `&mut MyStream -> ModalResult<Output>`.
30//! ```rust
31//! # use winnow::prelude::*;
32//! # type MyStream<'i> = &'i str;
33//! # type Output<'i> = &'i str;
34//! fn parser<'s>(i: &mut MyStream<'s>) -> ModalResult<Output<'s>> {
35//! "test".parse_next(i)
36//! }
37//! ```
38//!
39//! Like above, you'll need to implement the related token traits for `MyItem`.
40//!
41//! The traits you may want to implement for `MyStream` include:
42//!
43//! | trait | usage |
44//! |---|---|
45//! | [`Stream`] |Core trait for driving parsing|
46//! | [`StreamIsPartial`] | Marks the input as being the complete buffer or a partial buffer for streaming input |
47//! | [`AsBytes`] |Casts the input type to a byte slice|
48//! | [`AsBStr`] |Casts the input type to a slice of ASCII / UTF-8-like bytes|
49//! | [`Compare`] |Character comparison operations|
50//! | [`FindSlice`] |Look for a substring in self|
51//! | [`Location`] |Calculate location within initial input|
52//! | [`Offset`] |Calculate the offset between slices|
53//!
54//! And for `&[MyItem]` (slices returned by [`Stream`]):
55//!
56//! | trait | usage |
57//! |---|---|
58//! | [`SliceLen`] |Calculate the input length|
59//! | [`ParseSlice`] |Used to integrate `&str`'s `parse()` method|
60
61#![allow(unused_imports)] // Here for intra-dock links
62use super::lexing;
63use crate::stream::*;