| 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 |  | 
|---|