nom_methods/
methods.rs

1/// Makes a method from a parser combination
2///
3/// The must be set up because the compiler needs
4/// the information
5///
6/// ```ignore
7/// method!(my_function<Parser<'a> >( &[u8] ) -> &[u8], tag!("abcd"));
8/// // first type parameter is `self`'s type, second is input, third is output
9/// method!(my_function<Parser<'a>, &[u8], &[u8]>,     tag!("abcd"));
10/// //prefix them with 'pub' to make the methods public
11/// method!(pub my_function<Parser<'a>,&[u8], &[u8]>, tag!("abcd"));
12/// ```
13#[macro_export(local_inner_macros)]
14macro_rules! method (
15  // Non-public immutable self
16  ($name:ident( $i:ty ) -> $o:ty, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
17      #[allow(unused_variables)]
18      fn $name( &$self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i,$crate::lib::ErrorKind)> {
19        let result = $submac!(i, $($args)*);
20        result
21      }
22  );
23  ($name:ident<$i:ty,$o:ty,$e:ty>, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
24    #[allow(unused_variables)]
25    fn $name( &$self_, i: $i ) -> $crate::lib::IResult<$i, $o, $e> {
26      let result = $submac!(i, $($args)*);
27      result
28    }
29  );
30  ($name:ident<$i:ty,$o:ty>, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
31    #[allow(unused_variables)]
32    fn $name( &$self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)>  {
33      let result = $submac!(i, $($args)*);
34      result
35    }
36  );
37  ($name:ident<$o:ty>, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
38      #[allow(unused_variables)]
39      fn $name( &$self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], $o, (&[u8], $crate::lib::ErrorKind)> {
40        let result = $submac!(i, $($args)*);
41        result
42      }
43  );
44  ($name:ident, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
45      #[allow(unused_variables)]
46      fn $name( &$self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], &[u8], (&[u8], $crate::lib::ErrorKind)> {
47        let result = $submac!(i, $($args)*);
48        result
49      }
50  );
51  // Public immutable self
52  (pub $name:ident( $i:ty ) -> $o:ty, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
53      #[allow(unused_variables)]
54      pub fn $name( &$self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)> {
55        let result = $submac!(i, $($args)*);
56        result
57      }
58  );
59  (pub $name:ident<$i:ty,$o:ty,$e:ty>, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
60      #[allow(unused_variables)]
61      pub fn $name( &$self_, i: $i ) -> $crate::lib::IResult<$i, $o, $e> {
62        let result = $submac!(i, $($args)*);
63        result
64      }
65  );
66  (pub $name:ident<$i:ty,$o:ty>, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
67    #[allow(unused_variables)]
68    pub fn $name( &$self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)> {
69      let result = $submac!(i, $($args)*);
70      result
71    }
72  );
73  (pub $name:ident<$o:ty>, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
74    #[allow(unused_variables)]
75    pub fn $name( &$self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], $o, (&[u8], $crate::lib::ErrorKind)> {
76      let result = $submac!(i, $($args)*);
77      result
78    }
79  );
80  (pub $name:ident, &$self_:ident, $submac:ident!( $($args:tt)* )) => (
81    #[allow(unused_variables)]
82    pub fn $name( &$self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], &[u8], (&[u8], $crate::lib::ErrorKind)> {
83      let result = $submac!(i, $($args)*);
84      result
85    }
86  );
87  // Non-public mutable self
88  ($name:ident( $i:ty ) -> $o:ty, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
89      #[allow(unused_variables)]
90      fn $name( &mut $self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)> {
91        let result = $submac!(i, $($args)*);
92        result
93      }
94  );
95  ($name:ident<$i:ty,$o:ty,$e:ty>, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
96      #[allow(unused_variables)]
97      fn $name( &mut $self_, i: $i ) -> $crate::lib::IResult<$i, $o, $e> {
98        let result = $submac!(i, $($args)*);
99        result
100      }
101  );
102  ($name:ident<$i:ty,$o:ty>, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
103    #[allow(unused_variables)]
104    fn $name( &mut $self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)> {
105      let result = $submac!(i, $($args)*);
106      result
107    }
108  );
109  ($name:ident<$o:ty>, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
110      #[allow(unused_variables)]
111      fn $name( &mut $self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], $o, (&[u8], $crate::lib::ErrorKind)> {
112        let result = $submac!(i, $($args)*);
113        result
114      }
115  );
116  ($name:ident, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
117      #[allow(unused_variables)]
118      fn $name( &mut $self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], &[u8], (&[u8], $crate::lib::ErrorKind)> {
119        let result = $submac!(i, $($args)*);
120        result
121      }
122  );
123  // Public mutable self
124  (pub $name:ident( $i:ty ) -> $o:ty, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
125      #[allow(unused_variables)]
126      pub fn $name( &mut $self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)> {
127        let result = $submac!(i, $($args)*);
128        result
129      }
130  );
131  (pub $name:ident<$i:ty,$o:ty,$e:ty>, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
132      #[allow(unused_variables)]
133      pub fn $name( &mut $self_, i: $i ) -> $crate::lib::IResult<$i, $o, $e> {
134        let result = $submac!(i, $($args)*);
135        result
136      }
137  );
138  (pub $name:ident<$i:ty,$o:ty>, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
139    #[allow(unused_variables)]
140    pub fn $name( &mut $self_, i: $i ) -> $crate::lib::IResult<$i,$o,($i, $crate::lib::ErrorKind)> {
141      let result = $submac!(i, $($args)*);
142      result
143    }
144  );
145  (pub $name:ident<$o:ty>, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
146    #[allow(unused_variables)]
147    pub fn $name( &mut $self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], $o, (&[u8], $crate::lib::ErrorKind)> {
148      let result = $submac!(i, $($args)*);
149     result
150    }
151  );
152  (pub $name:ident, &mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
153    #[allow(unused_variables)]
154    pub fn $name( &mut $self_, i: &[u8] ) -> $crate::lib::IResult<&[u8], &[u8], (&[u8], $crate::lib::ErrorKind)> {
155      let result = $submac!(i, $($args)*);
156      result
157    }
158  );
159);
160
161/// Used to called methods then move self back into self
162#[macro_export(local_inner_macros)]
163macro_rules! call_m (
164  ($i:expr, $self_:ident.$method:ident) => (
165    {
166      $self_.$method($i)
167    }
168  );
169  ($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => (
170    {
171      $self_.$method($i, $($args),*)
172    }
173  );
174);
175
176/// emulate function currying for method calls on structs
177/// `apply_m!(self.my_function, arg1, arg2, ...)` becomes `self.my_function(input, arg1, arg2, ...)`
178///
179/// Supports up to 6 arguments
180#[macro_export(local_inner_macros)]
181macro_rules! apply_m (
182  ($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => ( {
183    $self_.$method( $i, $($args),* )
184  } );
185);
186
187#[cfg(test)]
188#[allow(deprecated)]
189mod tests {
190  // reproduce the tag_s and take_s macros, because of module import order
191  macro_rules! tag_s (
192    ($i:expr, $tag: expr) => (
193      {
194        use nom::{error::ErrorKind,Err,IResult};
195
196        let res: IResult<_,_> = if $tag.len() > $i.len() {
197          Err(Err::Error(error_position!($i, ErrorKind::Tag)))
198        //} else if &$i[0..$tag.len()] == $tag {
199        } else if ($i).starts_with($tag) {
200          Ok((&$i[$tag.len()..], &$i[0..$tag.len()]))
201        } else {
202          Err(Err::Error(error_position!($i, ErrorKind::Tag)))
203        };
204        res
205      }
206    );
207  );
208
209  macro_rules! take_s (
210    ($i:expr, $count:expr) => (
211      {
212        use nom::{IResult, Err, error::ErrorKind};
213
214        let cnt = $count as usize;
215        let res: IResult<_,_> = if $i.chars().count() < cnt {
216          Err(Err::Error(error_position!($i, ErrorKind::Tag)))
217        } else {
218          let mut offset = $i.len();
219          let mut count = 0;
220          for (o, _) in $i.char_indices() {
221            if count == cnt {
222              offset = o;
223              break;
224            }
225            count += 1;
226          }
227          Ok((&$i[offset..], &$i[..offset]))
228        };
229        res
230      }
231    );
232  );
233
234  struct Parser<'a> {
235    bcd: &'a str,
236  }
237
238  impl<'a> Parser<'a> {
239    pub fn new() -> Parser<'a> {
240      Parser { bcd: "" }
241    }
242
243    method!(
244      tag_abc<&'a str, &'a str>,
245      &self,
246      tag_s!("áβç")
247    );
248    method!(tag_bcd(&'a str) -> &'a str, &self, tag_s!("βçδ"));
249    method!(pub tag_hij(&'a str) -> &'a str, &self, tag_s!("λïJ"));
250    method!(pub tag_ijk<&'a str, &'a str>, &self, tag_s!("ïJƙ"));
251    method!(take3<&'a str, &'a str>, &self, take_s!(3));
252    method!(pub simple_call<&'a str, &'a str>, &mut self,
253      call_m!(self.tag_abc)
254    );
255    method!(pub simple_peek<&'a str, &'a str>, &mut self,
256      peek!(call_m!(self.take3))
257    );
258    method!(pub simple_chain<&'a str, &'a str>, &mut self,
259      do_parse!(
260         call_m!(self.tag_bcd_map)       >>
261         last: call_m!(self.simple_peek) >>
262         (last)
263      )
264    );
265
266    fn tag_bcd_map(&mut self, input: &'a str) -> ::lib::IResult<&'a str, &'a str> {
267      let (i, s) = self.tag_bcd(input)?;
268      self.bcd = s;
269
270      Ok((i, s))
271    }
272
273
274    fn tag_stuff(&mut self, input: &'a str, something: &'a str) -> ::lib::IResult<&'a str, &'a str> {
275      self.bcd = something;
276      self.tag_abc(input)
277    }
278    method!(use_apply<&'a str, &'a str>, &mut self, apply_m!(self.tag_stuff, "βçδ"));
279  }
280
281  #[test]
282  fn test_method_call_abc() {
283    let p = Parser::new();
284    let input: &str = "áβçδèƒϱλïJƙ";
285    let consumed: &str = "áβç";
286    let leftover: &str = "δèƒϱλïJƙ";
287    let res = p.tag_abc(input);
288    match res {
289      Ok((extra, output)) => {
290        assert!(
291          extra == leftover,
292          "`Parser.tag_abc` consumed leftover input. leftover: {}",
293          extra
294        );
295        assert!(
296          output == consumed,
297          "`Parser.tag_abc` doesnt return the string it consumed \
298           on success. Expected `{}`, got `{}`.",
299          consumed,
300          output
301        );
302      }
303      other => panic!(
304        "`Parser.tag_abc` didn't succeed when it should have. \
305         Got `{:?}`.",
306        other
307      ),
308    }
309  }
310
311  #[test]
312  fn test_method_call_bcd() {
313    let p = Parser::new();
314    let input: &str = "βçδèƒϱλïJƙ";
315    let consumed: &str = "βçδ";
316    let leftover: &str = "èƒϱλïJƙ";
317    let res = p.tag_bcd(input);
318    match res {
319      Ok((extra, output)) => {
320        assert!(
321          extra == leftover,
322          "`Parser.tag_bcd` consumed leftover input. leftover: {}",
323          extra
324        );
325        assert!(
326          output == consumed,
327          "`Parser.tag_bcd` doesn't return the string it consumed \
328           on success. Expected `{}`, got `{}`.",
329          consumed,
330          output
331        );
332      }
333      other => panic!(
334        "`Parser.tag_bcd` didn't succeed when it should have. \
335         Got `{:?}`.",
336        other
337      ),
338    }
339  }
340
341  #[test]
342  fn test_method_call_hij() {
343    let p = Parser::new();
344    let input: &str = "λïJƙℓ₥ñôƥ9řƨ";
345    let consumed: &str = "λïJ";
346    let leftover: &str = "ƙℓ₥ñôƥ9řƨ";
347    let res = p.tag_hij(input);
348    match res {
349      Ok((extra, output)) => {
350        assert!(
351          extra == leftover,
352          "`Parser.tag_hij` consumed leftover input. leftover: {}",
353          extra
354        );
355        assert!(
356          output == consumed,
357          "`Parser.tag_hij` doesn't return the string it consumed \
358           on success. Expected `{}`, got `{}`.",
359          consumed,
360          output
361        );
362      }
363      other => panic!(
364        "`Parser.tag_hij` didn't succeed when it should have. \
365         Got `{:?}`.",
366        other
367      ),
368    }
369  }
370
371  #[test]
372  fn test_method_call_ijk() {
373    let p = Parser::new();
374    let input: &str = "ïJƙℓ₥ñôƥ9řƨ";
375    let consumed: &str = "ïJƙ";
376    let leftover: &str = "ℓ₥ñôƥ9řƨ";
377    let res = p.tag_ijk(input);
378    match res {
379      Ok((extra, output)) => {
380        assert!(
381          extra == leftover,
382          "`Parser.tag_ijk` consumed leftover input. leftover: {}",
383          extra
384        );
385        assert!(
386          output == consumed,
387          "`Parser.tag_ijk` doesn't return the string it consumed \
388           on success. Expected `{}`, got `{}`.",
389          consumed,
390          output
391        );
392      }
393      other => panic!(
394        "`Parser.tag_ijk` didn't succeed when it should have. \
395         Got `{:?}`.",
396        other
397      ),
398    }
399  }
400  #[test]
401  fn test_method_simple_call() {
402    let mut p = Parser::new();
403    let input: &str = "áβçδèƒϱλïJƙ";
404    let consumed: &str = "áβç";
405    let leftover: &str = "δèƒϱλïJƙ";
406    let res = p.simple_call(input);
407    match res {
408      Ok((extra, output)) => {
409        assert!(
410          extra == leftover,
411          "`Parser.simple_call` consumed leftover input. leftover: {}",
412          extra
413        );
414        assert!(
415          output == consumed,
416          "`Parser.simple_call` doesn't return the string it consumed \
417           on success. Expected `{}`, got `{}`.",
418          consumed,
419          output
420        );
421      }
422      other => panic!(
423        "`Parser.simple_call` didn't succeed when it should have. \
424         Got `{:?}`.",
425        other
426      ),
427    }
428  }
429
430  #[test]
431  fn test_apply_m() {
432    let mut p = Parser::new();
433    let input: &str = "áβçδèƒϱλïJƙ";
434    let consumed: &str = "áβç";
435    let leftover: &str = "δèƒϱλïJƙ";
436    let res = p.use_apply(input);
437    match res {
438      Ok((extra, output)) => {
439        assert!(
440          extra == leftover,
441          "`Parser.use_apply` consumed leftover input. leftover: {}",
442          extra
443        );
444        assert!(
445          output == consumed,
446          "`Parser.use_apply` doesn't return the string it was supposed to \
447           on success. Expected `{}`, got `{}`.",
448          leftover,
449          output
450        );
451        assert!(
452          p.bcd == "βçδ",
453          "Parser.use_apply didn't modify the parser field correctly: {}",
454          p.bcd
455        );
456      }
457      other => panic!(
458        "`Parser.use_apply` didn't succeed when it should have. \
459         Got `{:?}`.",
460        other
461      ),
462    }
463  }
464
465  #[test]
466  fn test_method_call_peek() {
467    let mut p = Parser::new();
468    let input: &str = "ж¥ƺáβçδèƒϱλïJƙ";
469    let consumed: &str = "ж¥ƺ";
470    let res = p.simple_peek(input);
471    match res {
472      Ok((extra, output)) => {
473        assert!(
474          extra == input,
475          "`Parser.simple_peek` consumed leftover input. leftover: {}",
476          extra
477        );
478        assert!(
479          output == consumed,
480          "`Parser.simple_peek` doesn't return the string it consumed \
481           on success. Expected `{}`, got `{}`.",
482          consumed,
483          output
484        );
485      }
486      other => panic!(
487        "`Parser.simple_peek` didn't succeed when it should have. \
488         Got `{:?}`.",
489        other
490      ),
491    }
492  }
493
494  #[test]
495  fn test_method_call_chain() {
496    let mut p = Parser::new();
497    let input: &str = "βçδδèƒϱλïJƙℓ";
498    let leftover: &str = "δèƒϱλïJƙℓ";
499    let output: &str = "늟";
500    let res = p.simple_chain(input);
501    match res {
502      Ok((extra, out)) => {
503        assert!(
504          extra == leftover,
505          "`Parser.simple_chain` consumed leftover input. leftover: {}",
506          extra
507        );
508        assert!(
509          out == output,
510          "`Parser.simple_chain` doesn't return the string it was supposed to \
511           on success. Expected `{}`, got `{}`.",
512          output,
513          out
514        );
515        assert!(
516          p.bcd == "βçδ",
517          "Parser.simple_chain didn't modify the parser field correctly: {}",
518          p.bcd
519        );
520      }
521      other => panic!(
522        "`Parser.simple_chain` didn't succeed when it should have. \
523         Got `{:?}`.",
524        other
525      ),
526    }
527  }
528}