1 | //! # nom, eating data byte by byte |
2 | //! |
3 | //! nom is a parser combinator library with a focus on safe parsing, |
4 | //! streaming patterns, and as much as possible zero copy. |
5 | //! |
6 | //! ## Example |
7 | //! |
8 | //! ```rust |
9 | //! use nom::{ |
10 | //! IResult, |
11 | //! bytes::complete::{tag, take_while_m_n}, |
12 | //! combinator::map_res, |
13 | //! sequence::tuple}; |
14 | //! |
15 | //! #[derive(Debug,PartialEq)] |
16 | //! pub struct Color { |
17 | //! pub red: u8, |
18 | //! pub green: u8, |
19 | //! pub blue: u8, |
20 | //! } |
21 | //! |
22 | //! fn from_hex(input: &str) -> Result<u8, std::num::ParseIntError> { |
23 | //! u8::from_str_radix(input, 16) |
24 | //! } |
25 | //! |
26 | //! fn is_hex_digit(c: char) -> bool { |
27 | //! c.is_digit(16) |
28 | //! } |
29 | //! |
30 | //! fn hex_primary(input: &str) -> IResult<&str, u8> { |
31 | //! map_res( |
32 | //! take_while_m_n(2, 2, is_hex_digit), |
33 | //! from_hex |
34 | //! )(input) |
35 | //! } |
36 | //! |
37 | //! fn hex_color(input: &str) -> IResult<&str, Color> { |
38 | //! let (input, _) = tag("#" )(input)?; |
39 | //! let (input, (red, green, blue)) = tuple((hex_primary, hex_primary, hex_primary))(input)?; |
40 | //! |
41 | //! Ok((input, Color { red, green, blue })) |
42 | //! } |
43 | //! |
44 | //! fn main() { |
45 | //! assert_eq!(hex_color("#2F14DF" ), Ok(("" , Color { |
46 | //! red: 47, |
47 | //! green: 20, |
48 | //! blue: 223, |
49 | //! }))); |
50 | //! } |
51 | //! ``` |
52 | //! |
53 | //! The code is available on [Github](https://github.com/Geal/nom) |
54 | //! |
55 | //! There are a few [guides](https://github.com/Geal/nom/tree/main/doc) with more details |
56 | //! about [how to write parsers](https://github.com/Geal/nom/blob/main/doc/making_a_new_parser_from_scratch.md), |
57 | //! or the [error management system](https://github.com/Geal/nom/blob/main/doc/error_management.md). |
58 | //! You can also check out the [recipes] module that contains examples of common patterns. |
59 | //! |
60 | //! **Looking for a specific combinator? Read the |
61 | //! ["choose a combinator" guide](https://github.com/Geal/nom/blob/main/doc/choosing_a_combinator.md)** |
62 | //! |
63 | //! If you are upgrading to nom 5.0, please read the |
64 | //! [migration document](https://github.com/Geal/nom/blob/main/doc/upgrading_to_nom_5.md). |
65 | //! |
66 | //! ## Parser combinators |
67 | //! |
68 | //! Parser combinators are an approach to parsers that is very different from |
69 | //! software like [lex](https://en.wikipedia.org/wiki/Lex_(software)) and |
70 | //! [yacc](https://en.wikipedia.org/wiki/Yacc). Instead of writing the grammar |
71 | //! in a separate syntax and generating the corresponding code, you use very small |
72 | //! functions with very specific purposes, like "take 5 bytes", or "recognize the |
73 | //! word 'HTTP'", and assemble them in meaningful patterns like "recognize |
74 | //! 'HTTP', then a space, then a version". |
75 | //! The resulting code is small, and looks like the grammar you would have |
76 | //! written with other parser approaches. |
77 | //! |
78 | //! This gives us a few advantages: |
79 | //! |
80 | //! - The parsers are small and easy to write |
81 | //! - The parsers components are easy to reuse (if they're general enough, please add them to nom!) |
82 | //! - The parsers components are easy to test separately (unit tests and property-based tests) |
83 | //! - The parser combination code looks close to the grammar you would have written |
84 | //! - You can build partial parsers, specific to the data you need at the moment, and ignore the rest |
85 | //! |
86 | //! Here is an example of one such parser, to recognize text between parentheses: |
87 | //! |
88 | //! ```rust |
89 | //! use nom::{ |
90 | //! IResult, |
91 | //! sequence::delimited, |
92 | //! // see the "streaming/complete" paragraph lower for an explanation of these submodules |
93 | //! character::complete::char, |
94 | //! bytes::complete::is_not |
95 | //! }; |
96 | //! |
97 | //! fn parens(input: &str) -> IResult<&str, &str> { |
98 | //! delimited(char('(' ), is_not(")" ), char(')' ))(input) |
99 | //! } |
100 | //! ``` |
101 | //! |
102 | //! It defines a function named `parens` which will recognize a sequence of the |
103 | //! character `(`, the longest byte array not containing `)`, then the character |
104 | //! `)`, and will return the byte array in the middle. |
105 | //! |
106 | //! Here is another parser, written without using nom's combinators this time: |
107 | //! |
108 | //! ```rust |
109 | //! use nom::{IResult, Err, Needed}; |
110 | //! |
111 | //! # fn main() { |
112 | //! fn take4(i: &[u8]) -> IResult<&[u8], &[u8]>{ |
113 | //! if i.len() < 4 { |
114 | //! Err(Err::Incomplete(Needed::new(4))) |
115 | //! } else { |
116 | //! Ok((&i[4..], &i[0..4])) |
117 | //! } |
118 | //! } |
119 | //! # } |
120 | //! ``` |
121 | //! |
122 | //! This function takes a byte array as input, and tries to consume 4 bytes. |
123 | //! Writing all the parsers manually, like this, is dangerous, despite Rust's |
124 | //! safety features. There are still a lot of mistakes one can make. That's why |
125 | //! nom provides a list of functions to help in developing parsers. |
126 | //! |
127 | //! With functions, you would write it like this: |
128 | //! |
129 | //! ```rust |
130 | //! use nom::{IResult, bytes::streaming::take}; |
131 | //! fn take4(input: &str) -> IResult<&str, &str> { |
132 | //! take(4u8)(input) |
133 | //! } |
134 | //! ``` |
135 | //! |
136 | //! A parser in nom is a function which, for an input type `I`, an output type `O` |
137 | //! and an optional error type `E`, will have the following signature: |
138 | //! |
139 | //! ```rust,compile_fail |
140 | //! fn parser(input: I) -> IResult<I, O, E>; |
141 | //! ``` |
142 | //! |
143 | //! Or like this, if you don't want to specify a custom error type (it will be `(I, ErrorKind)` by default): |
144 | //! |
145 | //! ```rust,compile_fail |
146 | //! fn parser(input: I) -> IResult<I, O>; |
147 | //! ``` |
148 | //! |
149 | //! `IResult` is an alias for the `Result` type: |
150 | //! |
151 | //! ```rust |
152 | //! use nom::{Needed, error::Error}; |
153 | //! |
154 | //! type IResult<I, O, E = Error<I>> = Result<(I, O), Err<E>>; |
155 | //! |
156 | //! enum Err<E> { |
157 | //! Incomplete(Needed), |
158 | //! Error(E), |
159 | //! Failure(E), |
160 | //! } |
161 | //! ``` |
162 | //! |
163 | //! It can have the following values: |
164 | //! |
165 | //! - A correct result `Ok((I,O))` with the first element being the remaining of the input (not parsed yet), and the second the output value; |
166 | //! - An error `Err(Err::Error(c))` with `c` an error that can be built from the input position and a parser specific error |
167 | //! - An error `Err(Err::Incomplete(Needed))` indicating that more input is necessary. `Needed` can indicate how much data is needed |
168 | //! - An error `Err(Err::Failure(c))`. It works like the `Error` case, except it indicates an unrecoverable error: We cannot backtrack and test another parser |
169 | //! |
170 | //! Please refer to the ["choose a combinator" guide](https://github.com/Geal/nom/blob/main/doc/choosing_a_combinator.md) for an exhaustive list of parsers. |
171 | //! See also the rest of the documentation [here](https://github.com/Geal/nom/blob/main/doc). |
172 | //! |
173 | //! ## Making new parsers with function combinators |
174 | //! |
175 | //! nom is based on functions that generate parsers, with a signature like |
176 | //! this: `(arguments) -> impl Fn(Input) -> IResult<Input, Output, Error>`. |
177 | //! The arguments of a combinator can be direct values (like `take` which uses |
178 | //! a number of bytes or character as argument) or even other parsers (like |
179 | //! `delimited` which takes as argument 3 parsers, and returns the result of |
180 | //! the second one if all are successful). |
181 | //! |
182 | //! Here are some examples: |
183 | //! |
184 | //! ```rust |
185 | //! use nom::IResult; |
186 | //! use nom::bytes::complete::{tag, take}; |
187 | //! fn abcd_parser(i: &str) -> IResult<&str, &str> { |
188 | //! tag("abcd" )(i) // will consume bytes if the input begins with "abcd" |
189 | //! } |
190 | //! |
191 | //! fn take_10(i: &[u8]) -> IResult<&[u8], &[u8]> { |
192 | //! take(10u8)(i) // will consume and return 10 bytes of input |
193 | //! } |
194 | //! ``` |
195 | //! |
196 | //! ## Combining parsers |
197 | //! |
198 | //! There are higher level patterns, like the **`alt`** combinator, which |
199 | //! provides a choice between multiple parsers. If one branch fails, it tries |
200 | //! the next, and returns the result of the first parser that succeeds: |
201 | //! |
202 | //! ```rust |
203 | //! use nom::IResult; |
204 | //! use nom::branch::alt; |
205 | //! use nom::bytes::complete::tag; |
206 | //! |
207 | //! let mut alt_tags = alt((tag("abcd" ), tag("efgh" ))); |
208 | //! |
209 | //! assert_eq!(alt_tags(&b"abcdxxx" [..]), Ok((&b"xxx" [..], &b"abcd" [..]))); |
210 | //! assert_eq!(alt_tags(&b"efghxxx" [..]), Ok((&b"xxx" [..], &b"efgh" [..]))); |
211 | //! assert_eq!(alt_tags(&b"ijklxxx" [..]), Err(nom::Err::Error((&b"ijklxxx" [..], nom::error::ErrorKind::Tag)))); |
212 | //! ``` |
213 | //! |
214 | //! The **`opt`** combinator makes a parser optional. If the child parser returns |
215 | //! an error, **`opt`** will still succeed and return None: |
216 | //! |
217 | //! ```rust |
218 | //! use nom::{IResult, combinator::opt, bytes::complete::tag}; |
219 | //! fn abcd_opt(i: &[u8]) -> IResult<&[u8], Option<&[u8]>> { |
220 | //! opt(tag("abcd" ))(i) |
221 | //! } |
222 | //! |
223 | //! assert_eq!(abcd_opt(&b"abcdxxx" [..]), Ok((&b"xxx" [..], Some(&b"abcd" [..])))); |
224 | //! assert_eq!(abcd_opt(&b"efghxxx" [..]), Ok((&b"efghxxx" [..], None))); |
225 | //! ``` |
226 | //! |
227 | //! **`many0`** applies a parser 0 or more times, and returns a vector of the aggregated results: |
228 | //! |
229 | //! ```rust |
230 | //! # #[cfg (feature = "alloc" )] |
231 | //! # fn main() { |
232 | //! use nom::{IResult, multi::many0, bytes::complete::tag}; |
233 | //! use std::str; |
234 | //! |
235 | //! fn multi(i: &str) -> IResult<&str, Vec<&str>> { |
236 | //! many0(tag("abcd" ))(i) |
237 | //! } |
238 | //! |
239 | //! let a = "abcdef" ; |
240 | //! let b = "abcdabcdef" ; |
241 | //! let c = "azerty" ; |
242 | //! assert_eq!(multi(a), Ok(("ef" , vec!["abcd" ]))); |
243 | //! assert_eq!(multi(b), Ok(("ef" , vec!["abcd" , "abcd" ]))); |
244 | //! assert_eq!(multi(c), Ok(("azerty" , Vec::new()))); |
245 | //! # } |
246 | //! # #[cfg (not(feature = "alloc" ))] |
247 | //! # fn main() {} |
248 | //! ``` |
249 | //! |
250 | //! Here are some basic combinators available: |
251 | //! |
252 | //! - **`opt`**: Will make the parser optional (if it returns the `O` type, the new parser returns `Option<O>`) |
253 | //! - **`many0`**: Will apply the parser 0 or more times (if it returns the `O` type, the new parser returns `Vec<O>`) |
254 | //! - **`many1`**: Will apply the parser 1 or more times |
255 | //! |
256 | //! There are more complex (and more useful) parsers like `tuple`, which is |
257 | //! used to apply a series of parsers then assemble their results. |
258 | //! |
259 | //! Example with `tuple`: |
260 | //! |
261 | //! ```rust |
262 | //! # fn main() { |
263 | //! use nom::{error::ErrorKind, Needed, |
264 | //! number::streaming::be_u16, |
265 | //! bytes::streaming::{tag, take}, |
266 | //! sequence::tuple}; |
267 | //! |
268 | //! let mut tpl = tuple((be_u16, take(3u8), tag("fg" ))); |
269 | //! |
270 | //! assert_eq!( |
271 | //! tpl(&b"abcdefgh" [..]), |
272 | //! Ok(( |
273 | //! &b"h" [..], |
274 | //! (0x6162u16, &b"cde" [..], &b"fg" [..]) |
275 | //! )) |
276 | //! ); |
277 | //! assert_eq!(tpl(&b"abcde" [..]), Err(nom::Err::Incomplete(Needed::new(2)))); |
278 | //! let input = &b"abcdejk" [..]; |
279 | //! assert_eq!(tpl(input), Err(nom::Err::Error((&input[5..], ErrorKind::Tag)))); |
280 | //! # } |
281 | //! ``` |
282 | //! |
283 | //! But you can also use a sequence of combinators written in imperative style, |
284 | //! thanks to the `?` operator: |
285 | //! |
286 | //! ```rust |
287 | //! # fn main() { |
288 | //! use nom::{IResult, bytes::complete::tag}; |
289 | //! |
290 | //! #[derive(Debug, PartialEq)] |
291 | //! struct A { |
292 | //! a: u8, |
293 | //! b: u8 |
294 | //! } |
295 | //! |
296 | //! fn ret_int1(i:&[u8]) -> IResult<&[u8], u8> { Ok((i,1)) } |
297 | //! fn ret_int2(i:&[u8]) -> IResult<&[u8], u8> { Ok((i,2)) } |
298 | //! |
299 | //! fn f(i: &[u8]) -> IResult<&[u8], A> { |
300 | //! // if successful, the parser returns `Ok((remaining_input, output_value))` that we can destructure |
301 | //! let (i, _) = tag("abcd" )(i)?; |
302 | //! let (i, a) = ret_int1(i)?; |
303 | //! let (i, _) = tag("efgh" )(i)?; |
304 | //! let (i, b) = ret_int2(i)?; |
305 | //! |
306 | //! Ok((i, A { a, b })) |
307 | //! } |
308 | //! |
309 | //! let r = f(b"abcdefghX" ); |
310 | //! assert_eq!(r, Ok((&b"X" [..], A{a: 1, b: 2}))); |
311 | //! # } |
312 | //! ``` |
313 | //! |
314 | //! ## Streaming / Complete |
315 | //! |
316 | //! Some of nom's modules have `streaming` or `complete` submodules. They hold |
317 | //! different variants of the same combinators. |
318 | //! |
319 | //! A streaming parser assumes that we might not have all of the input data. |
320 | //! This can happen with some network protocol or large file parsers, where the |
321 | //! input buffer can be full and need to be resized or refilled. |
322 | //! |
323 | //! A complete parser assumes that we already have all of the input data. |
324 | //! This will be the common case with small files that can be read entirely to |
325 | //! memory. |
326 | //! |
327 | //! Here is how it works in practice: |
328 | //! |
329 | //! ```rust |
330 | //! use nom::{IResult, Err, Needed, error::{Error, ErrorKind}, bytes, character}; |
331 | //! |
332 | //! fn take_streaming(i: &[u8]) -> IResult<&[u8], &[u8]> { |
333 | //! bytes::streaming::take(4u8)(i) |
334 | //! } |
335 | //! |
336 | //! fn take_complete(i: &[u8]) -> IResult<&[u8], &[u8]> { |
337 | //! bytes::complete::take(4u8)(i) |
338 | //! } |
339 | //! |
340 | //! // both parsers will take 4 bytes as expected |
341 | //! assert_eq!(take_streaming(&b"abcde" [..]), Ok((&b"e" [..], &b"abcd" [..]))); |
342 | //! assert_eq!(take_complete(&b"abcde" [..]), Ok((&b"e" [..], &b"abcd" [..]))); |
343 | //! |
344 | //! // if the input is smaller than 4 bytes, the streaming parser |
345 | //! // will return `Incomplete` to indicate that we need more data |
346 | //! assert_eq!(take_streaming(&b"abc" [..]), Err(Err::Incomplete(Needed::new(1)))); |
347 | //! |
348 | //! // but the complete parser will return an error |
349 | //! assert_eq!(take_complete(&b"abc" [..]), Err(Err::Error(Error::new(&b"abc" [..], ErrorKind::Eof)))); |
350 | //! |
351 | //! // the alpha0 function recognizes 0 or more alphabetic characters |
352 | //! fn alpha0_streaming(i: &str) -> IResult<&str, &str> { |
353 | //! character::streaming::alpha0(i) |
354 | //! } |
355 | //! |
356 | //! fn alpha0_complete(i: &str) -> IResult<&str, &str> { |
357 | //! character::complete::alpha0(i) |
358 | //! } |
359 | //! |
360 | //! // if there's a clear limit to the recognized characters, both parsers work the same way |
361 | //! assert_eq!(alpha0_streaming("abcd;" ), Ok((";" , "abcd" ))); |
362 | //! assert_eq!(alpha0_complete("abcd;" ), Ok((";" , "abcd" ))); |
363 | //! |
364 | //! // but when there's no limit, the streaming version returns `Incomplete`, because it cannot |
365 | //! // know if more input data should be recognized. The whole input could be "abcd;", or |
366 | //! // "abcde;" |
367 | //! assert_eq!(alpha0_streaming("abcd" ), Err(Err::Incomplete(Needed::new(1)))); |
368 | //! |
369 | //! // while the complete version knows that all of the data is there |
370 | //! assert_eq!(alpha0_complete("abcd" ), Ok(("" , "abcd" ))); |
371 | //! ``` |
372 | //! **Going further:** Read the [guides](https://github.com/Geal/nom/tree/main/doc), |
373 | //! check out the [recipes]! |
374 | #![cfg_attr (not(feature = "std" ), no_std)] |
375 | #![cfg_attr (feature = "cargo-clippy" , allow(clippy::doc_markdown))] |
376 | #![cfg_attr (feature = "docsrs" , feature(doc_cfg))] |
377 | #![cfg_attr (feature = "docsrs" , feature(extended_key_value_attributes))] |
378 | #![deny (missing_docs)] |
379 | #[cfg_attr (nightly, warn(rustdoc::missing_doc_code_examples))] |
380 | #[cfg (feature = "alloc" )] |
381 | #[macro_use ] |
382 | extern crate alloc; |
383 | #[cfg (doctest)] |
384 | extern crate doc_comment; |
385 | |
386 | #[cfg (doctest)] |
387 | doc_comment::doctest!("../README.md" ); |
388 | |
389 | /// Lib module to re-export everything needed from `std` or `core`/`alloc`. This is how `serde` does |
390 | /// it, albeit there it is not public. |
391 | #[cfg_attr (nightly, allow(rustdoc::missing_doc_code_examples))] |
392 | pub mod lib { |
393 | /// `std` facade allowing `std`/`core` to be interchangeable. Reexports `alloc` crate optionally, |
394 | /// as well as `core` or `std` |
395 | #[cfg (not(feature = "std" ))] |
396 | #[cfg_attr (nightly, allow(rustdoc::missing_doc_code_examples))] |
397 | /// internal std exports for no_std compatibility |
398 | pub mod std { |
399 | #[doc (hidden)] |
400 | #[cfg (not(feature = "alloc" ))] |
401 | pub use core::borrow; |
402 | |
403 | #[cfg (feature = "alloc" )] |
404 | #[doc (hidden)] |
405 | pub use alloc::{borrow, boxed, string, vec}; |
406 | |
407 | #[doc (hidden)] |
408 | pub use core::{cmp, convert, fmt, iter, mem, ops, option, result, slice, str}; |
409 | |
410 | /// internal reproduction of std prelude |
411 | #[doc (hidden)] |
412 | pub mod prelude { |
413 | pub use core::prelude as v1; |
414 | } |
415 | } |
416 | |
417 | #[cfg (feature = "std" )] |
418 | #[cfg_attr (nightly, allow(rustdoc::missing_doc_code_examples))] |
419 | /// internal std exports for no_std compatibility |
420 | pub mod std { |
421 | #[doc (hidden)] |
422 | pub use std::{ |
423 | alloc, borrow, boxed, cmp, collections, convert, fmt, hash, iter, mem, ops, option, result, |
424 | slice, str, string, vec, |
425 | }; |
426 | |
427 | /// internal reproduction of std prelude |
428 | #[doc (hidden)] |
429 | pub mod prelude { |
430 | pub use std::prelude as v1; |
431 | } |
432 | } |
433 | } |
434 | |
435 | pub use self::bits::*; |
436 | pub use self::internal::*; |
437 | pub use self::traits::*; |
438 | |
439 | pub use self::str::*; |
440 | |
441 | #[macro_use ] |
442 | mod macros; |
443 | #[macro_use ] |
444 | pub mod error; |
445 | |
446 | pub mod branch; |
447 | pub mod combinator; |
448 | mod internal; |
449 | pub mod multi; |
450 | pub mod sequence; |
451 | mod traits; |
452 | |
453 | pub mod bits; |
454 | pub mod bytes; |
455 | |
456 | pub mod character; |
457 | |
458 | mod str; |
459 | |
460 | pub mod number; |
461 | |
462 | #[cfg (feature = "docsrs" )] |
463 | #[cfg_attr (feature = "docsrs" , cfg_attr(feature = "docsrs" , doc = include_str!("../doc/nom_recipes.md" )))] |
464 | pub mod recipes {} |
465 | |