winnow/
lib.rs

1//! > winnow, making parsing a breeze
2//!
3//! `winnow` is a parser combinator library
4//!
5//! Quick links:
6//! - [List of combinators][crate::combinator]
7//! - [Tutorial][_tutorial::chapter_0]
8//! - [Special Topics][_topic]
9//! - [Discussions](https://github.com/winnow-rs/winnow/discussions)
10//! - [CHANGELOG](https://github.com/winnow-rs/winnow/blob/v0.7.14/CHANGELOG.md) (includes major version migration
11//!   guides)
12//!
13//! ## Aspirations
14//!
15//! `winnow` aims to be your "do everything" parser, much like people treat regular expressions.
16//!
17//! In roughly priority order:
18//! 1. Support writing parser declaratively while not getting in the way of imperative-style
19//!    parsing when needed, working as an open-ended toolbox rather than a close-ended framework.
20//! 2. Flexible enough to be used for any application, including parsing strings, binary data,
21//!    or separate [lexing and parsing phases][_topic::lexing]
22//! 3. Zero-cost abstractions, making it easy to write high performance parsers
23//! 4. Easy to use, making it trivial for one-off uses
24//!
25//! In addition:
26//! - Resilient maintainership, including
27//!   - Willing to break compatibility rather than batching up breaking changes in large releases
28//!   - Leverage feature flags to keep one active branch
29//! - We will support the last 6 months of rust releases (MSRV, currently 1.64.0)
30//!
31//! See also [Special Topic: Why winnow?][crate::_topic::why]
32//!
33//! ## Example
34//!
35//! Run
36//! ```console
37//! $ cargo add winnow
38//! ```
39//!
40//! Then use it to parse:
41//! ```rust
42//! # #[cfg(feature = "alloc")] {
43#![doc = include_str!("../examples/css/parser.rs")]
44//! # }
45//! ```
46//!
47//! See also the [Tutorial][_tutorial::chapter_0] and [Special Topics][_topic]
48
49#![cfg_attr(docsrs, feature(doc_cfg))]
50#![cfg_attr(docsrs, feature(extended_key_value_attributes))]
51#![cfg_attr(all(not(feature = "std"), not(test)), no_std)]
52#![warn(missing_docs)]
53#![warn(clippy::std_instead_of_core)]
54#![warn(clippy::std_instead_of_alloc)]
55#![warn(clippy::print_stderr)]
56#![warn(clippy::print_stdout)]
57
58#[cfg(feature = "alloc")]
59#[cfg_attr(test, macro_use)]
60#[allow(unused_extern_crates)]
61extern crate alloc;
62
63#[doc = include_str!("../README.md")]
64#[cfg(doctest)]
65pub struct ReadmeDoctests;
66
67pub(crate) mod util {
68    #[allow(dead_code)]
69    pub(crate) fn from_fn<F: Fn(&mut core::fmt::Formatter<'_>) -> core::fmt::Result>(
70        f: F,
71    ) -> FromFn<F> {
72        FromFn(f)
73    }
74
75    pub(crate) struct FromFn<F>(F)
76    where
77        F: Fn(&mut core::fmt::Formatter<'_>) -> core::fmt::Result;
78
79    impl<F> core::fmt::Debug for FromFn<F>
80    where
81        F: Fn(&mut core::fmt::Formatter<'_>) -> core::fmt::Result,
82    {
83        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
84            (self.0)(f)
85        }
86    }
87
88    impl<F> core::fmt::Display for FromFn<F>
89    where
90        F: Fn(&mut core::fmt::Formatter<'_>) -> core::fmt::Result,
91    {
92        fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
93            (self.0)(f)
94        }
95    }
96}
97
98#[macro_use]
99mod macros;
100
101#[macro_use]
102pub mod error;
103
104mod parser;
105
106pub mod stream;
107
108pub mod ascii;
109pub mod binary;
110pub mod combinator;
111pub mod token;
112
113#[cfg(feature = "unstable-doc")]
114pub mod _topic;
115#[cfg(feature = "unstable-doc")]
116pub mod _tutorial;
117
118/// Core concepts available for glob import
119///
120/// Including
121/// - [`StreamIsPartial`][crate::stream::StreamIsPartial]
122/// - [`Parser`]
123///
124/// ## Example
125///
126/// ```rust
127/// use winnow::prelude::*;
128///
129/// fn parse_data(input: &mut &str) -> ModalResult<u64> {
130///     // ...
131/// #   winnow::ascii::dec_uint(input)
132/// }
133///
134/// fn main() {
135///   let result = parse_data.parse("100");
136///   assert_eq!(result, Ok(100));
137/// }
138/// ```
139pub mod prelude {
140    pub use crate::error::ModalError as _;
141    pub use crate::error::ParserError as _;
142    pub use crate::stream::AsChar as _;
143    pub use crate::stream::ContainsToken as _;
144    pub use crate::stream::Stream as _;
145    pub use crate::stream::StreamIsPartial as _;
146    pub use crate::ModalParser;
147    pub use crate::ModalResult;
148    pub use crate::Parser;
149    #[cfg(feature = "unstable-recover")]
150    #[cfg(feature = "std")]
151    pub use crate::RecoverableParser as _;
152
153    #[cfg(test)]
154    pub(crate) use crate::TestResult;
155}
156
157pub use error::ModalResult;
158pub use error::Result;
159pub use parser::*;
160pub use stream::BStr;
161pub use stream::Bytes;
162pub use stream::LocatingSlice;
163pub use stream::Partial;
164pub use stream::Stateful;
165pub use stream::Str;
166
167#[cfg(test)]
168pub(crate) use error::TestResult;