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.6.26/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 #![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)] 61 extern crate alloc; 62 #[cfg(doctest)] 63 extern crate doc_comment; 64 65 #[cfg(doctest)] 66 doc_comment::doctest!("../README.md"); 67 68 /// Lib module to re-export everything needed from `std` or `core`/`alloc`. This is how `serde` does 69 /// it, albeit there it is not public. 70 #[doc(hidden)] 71 pub(crate) mod lib { 72 #![allow(unused_imports)] 73 74 /// `std` facade allowing `std`/`core` to be interchangeable. Reexports `alloc` crate optionally, 75 /// as well as `core` or `std` 76 #[cfg(not(feature = "std"))] 77 /// internal std exports for no_std compatibility 78 pub(crate) mod std { 79 #[doc(hidden)] 80 #[cfg(not(feature = "alloc"))] 81 pub(crate) use core::borrow; 82 83 #[cfg(feature = "alloc")] 84 #[doc(hidden)] 85 pub(crate) use alloc::{borrow, boxed, collections, string, vec}; 86 87 #[doc(hidden)] 88 pub(crate) use core::{ 89 cmp, convert, fmt, hash, iter, mem, ops, option, result, slice, str, 90 }; 91 } 92 93 #[cfg(feature = "std")] 94 /// internal std exports for `no_std` compatibility 95 pub(crate) mod std { 96 #![allow(clippy::std_instead_of_core)] 97 #[doc(hidden)] 98 pub(crate) use std::{ 99 borrow, boxed, cmp, collections, convert, fmt, hash, iter, mem, ops, result, slice, 100 str, string, vec, 101 }; 102 } 103 } 104 105 #[macro_use] 106 mod macros; 107 108 #[macro_use] 109 pub mod error; 110 111 mod parser; 112 113 pub mod stream; 114 115 pub mod ascii; 116 pub mod binary; 117 pub mod combinator; 118 pub mod token; 119 120 #[cfg(feature = "unstable-doc")] 121 pub mod _topic; 122 #[cfg(feature = "unstable-doc")] 123 pub mod _tutorial; 124 125 /// Core concepts available for glob import 126 /// 127 /// Including 128 /// - [`StreamIsPartial`][crate::stream::StreamIsPartial] 129 /// - [`Parser`] 130 /// 131 /// ## Example 132 /// 133 /// ```rust 134 /// use winnow::prelude::*; 135 /// 136 /// fn parse_data(input: &mut &str) -> PResult<u64> { 137 /// // ... 138 /// # winnow::ascii::dec_uint(input) 139 /// } 140 /// 141 /// fn main() { 142 /// let result = parse_data.parse("100"); 143 /// assert_eq!(result, Ok(100)); 144 /// } 145 /// ``` 146 pub mod prelude { 147 pub use crate::stream::StreamIsPartial as _; 148 pub use crate::IResult; 149 pub use crate::ModalParser; 150 pub use crate::ModalResult; 151 pub use crate::PResult; 152 pub use crate::Parser; 153 #[cfg(feature = "unstable-recover")] 154 #[cfg(feature = "std")] 155 pub use crate::RecoverableParser as _; 156 } 157 158 pub use error::IResult; 159 pub use error::ModalResult; 160 pub use error::PResult; 161 pub use parser::*; 162 pub use stream::BStr; 163 pub use stream::Bytes; 164 #[allow(deprecated)] 165 pub use stream::Located; 166 pub use stream::LocatingSlice; 167 pub use stream::Partial; 168 pub use stream::Stateful; 169 pub use stream::Str; 170