nom_methods/
lib.rs

1//! Method macro combinators
2//!
3//! These macros make parsers as methods of structs
4//! and that can take methods of structs to call
5//! as parsers.
6//!
7//! There is a trick to make them easier to assemble,
8//! combinators are defined like this:
9//!
10//! ```ignore
11//! macro_rules! tag (
12//!   ($i:expr, $inp: expr) => (
13//!     {
14//!       ...
15//!     }
16//!   );
17//! );
18//! ```
19//!
20//! But when used as methods in other combinators, are used
21//! like this:
22//!
23//! ```ignore
24//! method!(my_function<Parser<'a> >, self, tag!("abcd"));
25//! ```
26//!
27//! Internally, other combinators will rewrite
28//! that call to pass the input as second argument:
29//!
30//! ```ignore
31//! macro_rules! method (
32//!   ($name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
33//!     fn $name( $self_: $a, i: &[u8] ) -> IResult<&[u8], &[u8]> {
34//!       $submac!(i, $($args)*)
35//!     }
36//!   );
37//! );
38//! ```
39//!
40//! The `method!` macro is similar to the `named!` macro in the macros module.
41//! While `named!` will create a parser function, `method!` will create a parser
42//! method on the struct it is defined in.
43//!
44//! Compared to the `named!` macro there are a few differences in how they are
45//! invoked. A `method!` invocation always has to have the type of `self`
46//! declared and it can't be a reference due to Rust's borrow lifetime
47//! restrictions:
48//!
49//! ```ignore
50//! //                  -`self`'s type-
51//! method!(method_name<  Parser<'a> >, ...);
52//! ```
53//! `self`'s type always comes first.
54//! The next difference is you have to input the self struct. Due to Rust's
55//! macro hygiene the macro can't declare it on it's own.
56//!
57//! ```ignore
58//! //                                                 -self-
59//! method!(method_name<Parser<'a>, &'a str, &'a str>, self, ...);
60//! ```
61//! When making a parsing struct with parsing methods, due to the static borrow
62//! checker,calling any parsing methods on self (or any other parsing struct)
63//! will cause self to be moved for the rest of the method.To get around this
64//! restriction all self is moved into the called method and then the called
65//! method will return self to the caller.
66//!
67//! To call a method on self you need to use the `call_m!` macro. For example:
68//!
69//! ```ignore
70//! struct<'a> Parser<'a> {
71//!   parsed: &'a str,
72//! }
73//! impl<'a> Parser<'a> {
74//!   // Constructor omitted for brevity
75//!   method!(take4<Parser<'a>, &'a str, &'a str>, self, take!(4));
76//!   method!(caller<Parser<'a>, &'a str, &'a str>, self, call_m!(self.take4));
77//! }
78//! ```
79//! More complicated combinations still mostly look the same as their `named!`
80//! counterparts:
81//!
82//! ```ignore
83//!    method!(pub simple_chain<&mut Parser<'a>, &'a str, &'a str>, self,
84//!      do_parse!(
85//!             call_m!(self.tag_abc)                                        >>
86//!             call_m!(self.tag_def)                                        >>
87//!             call_m!(self.tag_ghi)                                        >>
88//!       last: map!(call_m!(self.simple_peek), |parsed| sb.parsed = parsed) >>
89//!       (last)
90//!      )
91//!    );
92//! ```
93//! The three additions to method definitions to remember are:
94//! 1. Specify `self`'s type
95//! 2. Pass `self` to the macro
96//! 4. Call parser methods using the `call_m!` macro.
97
98#[macro_use]
99extern crate nom;
100
101pub mod lib {
102  pub use nom::{IResult, error::ErrorKind};
103}
104
105pub use self::methods::*;
106
107#[macro_use]
108mod methods;