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 | //! |
11 | //! ## Aspirations |
12 | //! |
13 | //! `winnow` aims to be your "do everything" parser, much like people treat regular expressions. |
14 | //! |
15 | //! In roughly priority order: |
16 | //! 1. Support writing parser declaratively while not getting in the way of imperative-style |
17 | //! parsing when needed, working as an open-ended toolbox rather than a close-ended framework. |
18 | //! 2. Flexible enough to be used for any application, including parsing binary data, strings, or |
19 | //! separate lexing and parsing phases |
20 | //! 3. Zero-cost abstractions, making it easy to write high performance parsers |
21 | //! 4. Easy to use, making it trivial for one-off uses |
22 | //! |
23 | //! In addition: |
24 | //! - Resilient maintainership, including |
25 | //! - Willing to break compatibility rather than batching up breaking changes in large releases |
26 | //! - Leverage feature flags to keep one active branch |
27 | //! - We will support the last 6 months of rust releases (MSRV, currently 1.64.0) |
28 | //! |
29 | //! See also [Special Topic: Why winnow?][crate::_topic::why] |
30 | //! |
31 | //! ## Example |
32 | //! |
33 | //! Run |
34 | //! ```console |
35 | //! $ cargo add winnow |
36 | //! ``` |
37 | //! |
38 | //! Then use it to parse: |
39 | //! ```rust |
40 | //! # #[cfg (feature = "alloc" )] { |
41 | #![doc = include_str!("../examples/css/parser.rs" )] |
42 | //! # } |
43 | //! ``` |
44 | //! |
45 | //! See also the [Tutorial][_tutorial::chapter_0] and [Special Topics][_topic] |
46 | |
47 | #![cfg_attr (docsrs, feature(doc_auto_cfg))] |
48 | #![cfg_attr (docsrs, feature(doc_cfg))] |
49 | #![cfg_attr (docsrs, feature(extended_key_value_attributes))] |
50 | #![cfg_attr (not(feature = "std" ), no_std)] |
51 | #![warn (missing_docs)] |
52 | // BEGIN - Embark standard lints v6 for Rust 1.55+ |
53 | // do not change or add/remove here, but one can add exceptions after this section |
54 | // for more info see: <https://github.com/EmbarkStudios/rust-ecosystem/issues/59> |
55 | // "-Dunsafe_code", |
56 | #![warn (clippy::all)] |
57 | #![warn (clippy::await_holding_lock)] |
58 | #![warn (clippy::char_lit_as_u8)] |
59 | #![warn (clippy::checked_conversions)] |
60 | #![warn (clippy::dbg_macro)] |
61 | #![warn (clippy::debug_assert_with_mut_call)] |
62 | #![warn (clippy::doc_markdown)] |
63 | #![warn (clippy::empty_enum)] |
64 | #![warn (clippy::enum_glob_use)] |
65 | #![warn (clippy::exit)] |
66 | #![warn (clippy::expl_impl_clone_on_copy)] |
67 | #![warn (clippy::explicit_deref_methods)] |
68 | #![warn (clippy::explicit_into_iter_loop)] |
69 | #![warn (clippy::fallible_impl_from)] |
70 | #![warn (clippy::filter_map_next)] |
71 | #![warn (clippy::flat_map_option)] |
72 | #![warn (clippy::float_cmp_const)] |
73 | #![warn (clippy::fn_params_excessive_bools)] |
74 | #![warn (clippy::from_iter_instead_of_collect)] |
75 | #![warn (clippy::if_let_mutex)] |
76 | #![warn (clippy::implicit_clone)] |
77 | #![warn (clippy::imprecise_flops)] |
78 | #![warn (clippy::inefficient_to_string)] |
79 | #![warn (clippy::invalid_upcast_comparisons)] |
80 | #![warn (clippy::large_digit_groups)] |
81 | #![warn (clippy::large_stack_arrays)] |
82 | #![warn (clippy::large_types_passed_by_value)] |
83 | #![warn (clippy::let_unit_value)] |
84 | #![warn (clippy::linkedlist)] |
85 | #![warn (clippy::lossy_float_literal)] |
86 | #![warn (clippy::macro_use_imports)] |
87 | #![warn (clippy::manual_ok_or)] |
88 | #![warn (clippy::map_err_ignore)] |
89 | #![warn (clippy::map_flatten)] |
90 | #![warn (clippy::map_unwrap_or)] |
91 | #![warn (clippy::match_on_vec_items)] |
92 | #![warn (clippy::match_same_arms)] |
93 | #![warn (clippy::match_wild_err_arm)] |
94 | #![warn (clippy::match_wildcard_for_single_variants)] |
95 | #![warn (clippy::mem_forget)] |
96 | #![warn (clippy::mismatched_target_os)] |
97 | #![warn (clippy::missing_enforced_import_renames)] |
98 | #![warn (clippy::mut_mut)] |
99 | #![warn (clippy::mutex_integer)] |
100 | #![warn (clippy::needless_borrow)] |
101 | #![warn (clippy::needless_continue)] |
102 | #![warn (clippy::needless_for_each)] |
103 | #![warn (clippy::option_option)] |
104 | #![warn (clippy::path_buf_push_overwrite)] |
105 | #![warn (clippy::ptr_as_ptr)] |
106 | #![warn (clippy::rc_mutex)] |
107 | #![warn (clippy::ref_option_ref)] |
108 | #![warn (clippy::rest_pat_in_fully_bound_structs)] |
109 | #![warn (clippy::same_functions_in_if_condition)] |
110 | #![warn (clippy::semicolon_if_nothing_returned)] |
111 | #![warn (clippy::single_match_else)] |
112 | #![warn (clippy::string_add_assign)] |
113 | #![warn (clippy::string_add)] |
114 | #![warn (clippy::string_lit_as_bytes)] |
115 | #![warn (clippy::string_to_string)] |
116 | #![warn (clippy::todo)] |
117 | #![warn (clippy::trait_duplication_in_bounds)] |
118 | #![warn (clippy::unimplemented)] |
119 | #![warn (clippy::unnested_or_patterns)] |
120 | #![warn (clippy::unused_self)] |
121 | #![warn (clippy::useless_transmute)] |
122 | #![warn (clippy::verbose_file_reads)] |
123 | #![warn (clippy::zero_sized_map_values)] |
124 | #![warn (future_incompatible)] |
125 | #![warn (nonstandard_style)] |
126 | #![warn (rust_2018_idioms)] |
127 | // END - Embark standard lints v6 for Rust 1.55+ |
128 | #![allow (clippy::branches_sharing_code)] |
129 | #![allow (clippy::collapsible_else_if)] |
130 | #![allow (clippy::if_same_then_else)] |
131 | #![allow (clippy::bool_assert_comparison)] |
132 | #![allow (clippy::let_and_return)] |
133 | #![allow (clippy::assertions_on_constants)] |
134 | #![allow (clippy::map_unwrap_or)] |
135 | #![allow (clippy::single_match_else)] |
136 | #![allow (clippy::single_match)] |
137 | #![allow (clippy::unnested_or_patterns)] |
138 | #[cfg_attr (nightly, warn(rustdoc::missing_doc_code_examples))] |
139 | #[cfg (feature = "alloc" )] |
140 | #[macro_use ] |
141 | extern crate alloc; |
142 | #[cfg (doctest)] |
143 | extern crate doc_comment; |
144 | |
145 | #[cfg (doctest)] |
146 | doc_comment::doctest!("../README.md" ); |
147 | |
148 | /// Lib module to re-export everything needed from `std` or `core`/`alloc`. This is how `serde` does |
149 | /// it, albeit there it is not public. |
150 | #[doc (hidden)] |
151 | pub(crate) mod lib { |
152 | /// `std` facade allowing `std`/`core` to be interchangeable. Reexports `alloc` crate optionally, |
153 | /// as well as `core` or `std` |
154 | #[cfg (not(feature = "std" ))] |
155 | /// internal std exports for no_std compatibility |
156 | pub mod std { |
157 | #[doc (hidden)] |
158 | #[cfg (not(feature = "alloc" ))] |
159 | pub use core::borrow; |
160 | |
161 | #[cfg (feature = "alloc" )] |
162 | #[doc (hidden)] |
163 | pub use alloc::{borrow, boxed, collections, string, vec}; |
164 | |
165 | #[doc (hidden)] |
166 | pub use core::{cmp, convert, fmt, hash, iter, mem, ops, option, result, slice, str}; |
167 | |
168 | /// internal reproduction of std prelude |
169 | #[doc (hidden)] |
170 | pub mod prelude { |
171 | pub use core::prelude as v1; |
172 | } |
173 | } |
174 | |
175 | #[cfg (feature = "std" )] |
176 | /// internal std exports for `no_std` compatibility |
177 | pub mod std { |
178 | #[doc (hidden)] |
179 | pub use std::{ |
180 | alloc, borrow, boxed, cmp, collections, convert, fmt, hash, iter, mem, ops, option, |
181 | result, slice, str, string, vec, |
182 | }; |
183 | |
184 | /// internal reproduction of std prelude |
185 | #[doc (hidden)] |
186 | pub mod prelude { |
187 | pub use std::prelude as v1; |
188 | } |
189 | } |
190 | } |
191 | |
192 | #[macro_use ] |
193 | mod macros; |
194 | |
195 | #[macro_use ] |
196 | pub mod error; |
197 | |
198 | mod parser; |
199 | |
200 | pub mod stream; |
201 | |
202 | pub mod ascii; |
203 | pub mod binary; |
204 | pub mod bits; |
205 | pub mod branch; |
206 | pub mod bytes; |
207 | pub mod character; |
208 | pub mod combinator; |
209 | pub mod multi; |
210 | pub mod number; |
211 | pub mod sequence; |
212 | pub mod token; |
213 | pub mod trace; |
214 | |
215 | #[cfg (feature = "unstable-doc" )] |
216 | pub mod _topic; |
217 | #[cfg (feature = "unstable-doc" )] |
218 | pub mod _tutorial; |
219 | |
220 | /// Core concepts available for glob import |
221 | /// |
222 | /// Including |
223 | /// - [`FinishIResult`] |
224 | /// - [`Parser`] |
225 | /// |
226 | /// ## Example |
227 | /// |
228 | /// ```rust |
229 | /// use winnow::prelude::*; |
230 | /// |
231 | /// fn parse_data(input: &str) -> IResult<&str, u64> { |
232 | /// // ... |
233 | /// # winnow::ascii::dec_uint(input) |
234 | /// } |
235 | /// |
236 | /// fn main() { |
237 | /// let result = parse_data.parse("100" ); |
238 | /// assert_eq!(result, Ok(100)); |
239 | /// } |
240 | /// ``` |
241 | pub mod prelude { |
242 | pub use crate::stream::StreamIsPartial as _; |
243 | #[allow (deprecated)] |
244 | pub use crate::FinishIResult as _; |
245 | pub use crate::IResult; |
246 | pub use crate::Parser; |
247 | } |
248 | |
249 | #[allow (deprecated)] |
250 | pub use error::FinishIResult; |
251 | pub use error::IResult; |
252 | pub use parser::*; |
253 | pub use stream::BStr; |
254 | pub use stream::Bytes; |
255 | pub use stream::Located; |
256 | pub use stream::Partial; |
257 | pub use stream::Stateful; |
258 | pub use stream::Str; |
259 | |