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;