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.5.40/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 binary data, strings, or |
21 | //! separate lexing and parsing phases |
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_auto_cfg))] |
50 | #![cfg_attr (docsrs, feature(doc_cfg))] |
51 | #![cfg_attr (docsrs, feature(extended_key_value_attributes))] |
52 | #![cfg_attr (not(feature = "std" ), no_std)] |
53 | #![warn (missing_docs)] |
54 | #![warn (clippy::std_instead_of_core)] |
55 | // BEGIN - Embark standard lints v6 for Rust 1.55+ |
56 | // do not change or add/remove here, but one can add exceptions after this section |
57 | // for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59> |
58 | // "-Dunsafe_code", |
59 | #![warn (clippy::all)] |
60 | #![warn (clippy::await_holding_lock)] |
61 | #![warn (clippy::char_lit_as_u8)] |
62 | #![warn (clippy::checked_conversions)] |
63 | #![warn (clippy::dbg_macro)] |
64 | #![warn (clippy::debug_assert_with_mut_call)] |
65 | #![warn (clippy::doc_markdown)] |
66 | #![warn (clippy::empty_enum)] |
67 | #![warn (clippy::enum_glob_use)] |
68 | #![warn (clippy::exit)] |
69 | #![warn (clippy::expl_impl_clone_on_copy)] |
70 | #![warn (clippy::explicit_deref_methods)] |
71 | #![warn (clippy::explicit_into_iter_loop)] |
72 | #![warn (clippy::fallible_impl_from)] |
73 | #![warn (clippy::filter_map_next)] |
74 | #![warn (clippy::flat_map_option)] |
75 | #![warn (clippy::float_cmp_const)] |
76 | #![warn (clippy::fn_params_excessive_bools)] |
77 | #![warn (clippy::from_iter_instead_of_collect)] |
78 | #![warn (clippy::if_let_mutex)] |
79 | #![warn (clippy::implicit_clone)] |
80 | #![warn (clippy::imprecise_flops)] |
81 | #![warn (clippy::inefficient_to_string)] |
82 | #![warn (clippy::invalid_upcast_comparisons)] |
83 | #![warn (clippy::large_digit_groups)] |
84 | #![warn (clippy::large_stack_arrays)] |
85 | #![warn (clippy::large_types_passed_by_value)] |
86 | #![warn (clippy::let_unit_value)] |
87 | #![warn (clippy::linkedlist)] |
88 | #![warn (clippy::lossy_float_literal)] |
89 | #![warn (clippy::macro_use_imports)] |
90 | #![warn (clippy::manual_ok_or)] |
91 | #![warn (clippy::map_err_ignore)] |
92 | #![warn (clippy::map_flatten)] |
93 | #![warn (clippy::map_unwrap_or)] |
94 | #![warn (clippy::match_on_vec_items)] |
95 | #![warn (clippy::match_same_arms)] |
96 | #![warn (clippy::match_wild_err_arm)] |
97 | #![warn (clippy::match_wildcard_for_single_variants)] |
98 | #![warn (clippy::mem_forget)] |
99 | #![warn (clippy::mismatched_target_os)] |
100 | #![warn (clippy::missing_enforced_import_renames)] |
101 | #![warn (clippy::mut_mut)] |
102 | #![warn (clippy::mutex_integer)] |
103 | #![warn (clippy::needless_borrow)] |
104 | #![warn (clippy::needless_continue)] |
105 | #![warn (clippy::needless_for_each)] |
106 | #![warn (clippy::option_option)] |
107 | #![warn (clippy::path_buf_push_overwrite)] |
108 | #![warn (clippy::ptr_as_ptr)] |
109 | #![warn (clippy::rc_mutex)] |
110 | #![warn (clippy::ref_option_ref)] |
111 | #![warn (clippy::rest_pat_in_fully_bound_structs)] |
112 | #![warn (clippy::same_functions_in_if_condition)] |
113 | #![warn (clippy::semicolon_if_nothing_returned)] |
114 | #![warn (clippy::single_match_else)] |
115 | #![warn (clippy::string_add_assign)] |
116 | #![warn (clippy::string_add)] |
117 | #![warn (clippy::string_lit_as_bytes)] |
118 | #![warn (clippy::string_to_string)] |
119 | #![warn (clippy::todo)] |
120 | #![warn (clippy::trait_duplication_in_bounds)] |
121 | #![warn (clippy::unimplemented)] |
122 | #![warn (clippy::unnested_or_patterns)] |
123 | #![warn (clippy::unused_self)] |
124 | #![warn (clippy::useless_transmute)] |
125 | #![warn (clippy::verbose_file_reads)] |
126 | #![warn (clippy::zero_sized_map_values)] |
127 | #![warn (future_incompatible)] |
128 | #![warn (nonstandard_style)] |
129 | #![warn (rust_2018_idioms)] |
130 | // END - Embark standard lints v6 for Rust 1.55+ |
131 | #![allow (clippy::branches_sharing_code)] |
132 | #![allow (clippy::collapsible_else_if)] |
133 | #![allow (clippy::if_same_then_else)] |
134 | #![allow (clippy::bool_assert_comparison)] |
135 | #![allow (clippy::let_and_return)] |
136 | #![allow (clippy::assertions_on_constants)] |
137 | #![allow (clippy::map_unwrap_or)] |
138 | #![allow (clippy::single_match_else)] |
139 | #![allow (clippy::single_match)] |
140 | #![allow (clippy::unnested_or_patterns)] |
141 | #![allow (deprecated)] |
142 | #[cfg_attr (nightly, warn(rustdoc::missing_doc_code_examples))] |
143 | #[cfg (feature = "alloc" )] |
144 | #[cfg_attr (test, macro_use)] |
145 | extern crate alloc; |
146 | #[cfg (doctest)] |
147 | extern crate doc_comment; |
148 | |
149 | #[cfg (doctest)] |
150 | doc_comment::doctest!("../README.md" ); |
151 | |
152 | /// Lib module to re-export everything needed from `std` or `core`/`alloc`. This is how `serde` does |
153 | /// it, albeit there it is not public. |
154 | #[doc (hidden)] |
155 | pub(crate) mod lib { |
156 | /// `std` facade allowing `std`/`core` to be interchangeable. Reexports `alloc` crate optionally, |
157 | /// as well as `core` or `std` |
158 | #[cfg (not(feature = "std" ))] |
159 | /// internal std exports for no_std compatibility |
160 | pub mod std { |
161 | #[doc (hidden)] |
162 | #[cfg (not(feature = "alloc" ))] |
163 | pub use core::borrow; |
164 | |
165 | #[cfg (feature = "alloc" )] |
166 | #[doc (hidden)] |
167 | pub use alloc::{borrow, boxed, collections, string, vec}; |
168 | |
169 | #[doc (hidden)] |
170 | pub use core::{cmp, convert, fmt, hash, iter, mem, ops, option, result, slice, str}; |
171 | |
172 | /// internal reproduction of std prelude |
173 | #[doc (hidden)] |
174 | pub mod prelude { |
175 | pub use core::prelude as v1; |
176 | } |
177 | } |
178 | |
179 | #[cfg (feature = "std" )] |
180 | /// internal std exports for `no_std` compatibility |
181 | pub mod std { |
182 | #![allow (clippy::std_instead_of_core)] |
183 | #[doc (hidden)] |
184 | pub use std::{ |
185 | alloc, borrow, boxed, cmp, collections, convert, fmt, hash, iter, mem, ops, option, |
186 | result, slice, str, string, vec, |
187 | }; |
188 | |
189 | /// internal reproduction of std prelude |
190 | #[doc (hidden)] |
191 | pub mod prelude { |
192 | pub use std::prelude as v1; |
193 | } |
194 | } |
195 | } |
196 | |
197 | #[macro_use ] |
198 | mod macros; |
199 | |
200 | #[macro_use ] |
201 | pub mod error; |
202 | |
203 | mod parser; |
204 | |
205 | pub mod stream; |
206 | |
207 | pub mod ascii; |
208 | pub mod binary; |
209 | pub mod combinator; |
210 | pub mod token; |
211 | pub mod trace; |
212 | |
213 | #[cfg (feature = "unstable-doc" )] |
214 | pub mod _topic; |
215 | #[cfg (feature = "unstable-doc" )] |
216 | pub mod _tutorial; |
217 | |
218 | /// Core concepts available for glob import |
219 | /// |
220 | /// Including |
221 | /// - [`StreamIsPartial`][crate::stream::StreamIsPartial] |
222 | /// - [`Parser`] |
223 | /// |
224 | /// ## Example |
225 | /// |
226 | /// ```rust |
227 | /// use winnow::prelude::*; |
228 | /// |
229 | /// fn parse_data(input: &mut &str) -> PResult<u64> { |
230 | /// // ... |
231 | /// # winnow::ascii::dec_uint(input) |
232 | /// } |
233 | /// |
234 | /// fn main() { |
235 | /// let result = parse_data.parse("100" ); |
236 | /// assert_eq!(result, Ok(100)); |
237 | /// } |
238 | /// ``` |
239 | pub mod prelude { |
240 | pub use crate::stream::StreamIsPartial as _; |
241 | pub use crate::IResult; |
242 | pub use crate::PResult; |
243 | pub use crate::Parser; |
244 | #[cfg (feature = "unstable-recover" )] |
245 | pub use crate::RecoverableParser as _; |
246 | } |
247 | |
248 | pub use error::IResult; |
249 | pub use error::PResult; |
250 | pub use parser::*; |
251 | pub use stream::BStr; |
252 | pub use stream::Bytes; |
253 | pub use stream::Located; |
254 | pub use stream::Partial; |
255 | pub use stream::Stateful; |
256 | pub use stream::Str; |
257 | |