From 9b3f69d7f4a6b8e1b0b4ec1a4ded0634c93834ea Mon Sep 17 00:00:00 2001 From: Jeremy Wall Date: Wed, 5 Sep 2018 22:02:00 -0500 Subject: [PATCH] REFACTOR: Fix issue where text_token macro expected a reference. --- src/macros.rs | 34 ++++++++++++++++++++++++++++++++-- src/test.rs | 6 +++--- 2 files changed, 35 insertions(+), 5 deletions(-) diff --git a/src/macros.rs b/src/macros.rs index fbdf92b..e3c2d1b 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -1,6 +1,7 @@ //! Contains the helper macros for abortable-parser. /// Convenience macro for looking for a specific text token in a byte input stream. +#[macro_export] macro_rules! text_token { ($i:expr, $e:expr) => {{ use $crate::Error; @@ -19,19 +20,22 @@ macro_rules! text_token { if count == $e.len() { Result::Complete(_i.clone(), $e) } else { - Result::Fail(Error::new(format!("Expected {} but didn't get it.", $e), $i)) + Result::Fail(Error::new(format!("Expected {} but didn't get it.", $e), &$i)) } }}; } // FIXME(jwall): We need until!, not! and peek!. - /// Converts a function indentifier into a macro call. Useful when writing your own macro combinator. #[macro_export] macro_rules! run { ($i:expr, $f:ident) => { $f($i) }; + + ($i:expr, $f:ident( $( $args:tt )* ) ) => { + $f($i, $($args)*) + }; } /// Turns Fails into Aborts. Allows you to turn any parse failure into a hard abort of the parser. @@ -46,6 +50,10 @@ macro_rules! must { } }; + ($i:expr, $f:ident( $( $args:tt )* ) ) => { + must!($i, run!($f($($args)*))) + }; + ($i:expr, $f:ident) => { must!($i, run!($f)) }; @@ -65,6 +73,10 @@ macro_rules! wrap_err { } }}; + ($i:expr, $f:ident( $( $args:tt )* ), $e:expr ) => { + wrap_err!($i, run!($f($($args)*)), $e:expr) + }; + ($i:expr, $f:ident, $e:expr) => { wrap_err!($i, run!($f), $e) }; @@ -82,6 +94,10 @@ macro_rules! trap { } }; + ($i:expr, $f:ident( $( $args:tt )* ) ) => { + trap!($i, run!($f($($args)*))) + }; + ($i:expr, $f:ident) => { trap!($i, run!($f)) }; @@ -101,6 +117,10 @@ macro_rules! must_complete { } }}; + ($i:expr, $efn:expr, $f:ident( $( $args:tt )* ) ) => { + must_complete!($i, $efn, run!($f($($args)*))) + }; + ($i:expr, $efn:expr, $f:ident) => { must_complete!($i, $efn, run!($f)) }; @@ -153,6 +173,16 @@ macro_rules! do_each { do_each!($i, _ => run!($f), $( $rest )* ) }; + ($i:expr, $val:ident => $f:ident( $(args:tt)* ), $($rest:tt)* ) => { + // If any single one of these matchers fails then all of them are failures. + do_each!($i, $val => run!($f($($args)*)), $( $rest )* ) + }; + + ($i:expr, _ => $f:ident( $(args:tt)* ), $($rest:tt)* ) => { + // If any single one of these matchers fails then all of them are failures. + do_each!($i, _ => run!($f($($args)*)), $( $rest )* ) + }; + // Our Terminal condition ($i:expr, ( $($rest:tt)* ) ) => { Result::Complete($i, ($($rest)*)) diff --git a/src/test.rs b/src/test.rs index 40937c5..2b77333 100644 --- a/src/test.rs +++ b/src/test.rs @@ -1,5 +1,5 @@ -use super::iter::SliceIter; use super::{Offsetable, Result}; +use iter::SliceIter; #[test] fn test_slice_iter() { @@ -70,7 +70,7 @@ fn parse_three(i: SliceIter) -> Result, String, String> { fn test_text_token() { let input_str = "foo bar"; let iter = SliceIter::new(input_str.as_bytes()); - let result = text_token!(&iter, "foo"); + let result = text_token!(iter, "foo"); assert!(result.is_complete()); if let Result::Complete(i, o) = result { assert_eq!(i.get_offset(), 3); @@ -82,7 +82,7 @@ fn test_text_token() { fn test_text_token_fails() { let input_str = "foo bar"; let iter = SliceIter::new(input_str.as_bytes()); - let result = text_token!(&iter, "bar"); + let result = text_token!(iter, "bar"); assert!(result.is_fail()); }