#[macro_export]
macro_rules! method (
($name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty,$i:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], $o, u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty>( $i:ty ) -> $o:ty, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty,$i:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( $self_: $a,i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty,$o:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], $o, u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty>, $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty>( $i:ty ) -> $o:ty, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty,$i:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], $o, u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
($name:ident<$a:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty>( $i:ty ) -> $o:ty, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty,$i:ty,$o:ty,$e:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( mut $self_: $a, i: $i ) -> ($a, $crate::IResult<$i, $o, $e>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty,$i:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( mut $self_: $a,i: $i ) -> ($a, $crate::IResult<$i,$o,u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty,$o:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], $o, u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
(pub $name:ident<$a:ty>, mut $self_:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( mut $self_: $a, i: &[u8] ) -> ($a, $crate::IResult<&[u8], &[u8], u32>) {
let result = $submac!(i, $($args)*);
($self_, result)
}
);
);
#[macro_export]
macro_rules! call_m (
($i:expr, $self_:ident.$method:ident) => (
{
let (tmp, res) = $self_.$method($i);
$self_ = tmp;
res
}
);
($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => (
{
let (tmp, res) = $self_.$method($i, $($args),*);
$self_ = tmp;
res
}
);
);
#[macro_export]
macro_rules! apply_m (
($i:expr, $self_:ident.$method:ident, $($args:expr),* ) => ( { let (tmp, res) = $self_.$method( $i, $($args),* ); $self_ = tmp; res } );
);
#[cfg(test)]
mod tests {
use internal::IResult::*;
macro_rules! tag_s (
($i:expr, $tag: expr) => (
{
let res: $crate::IResult<_,_> = if $tag.len() > $i.len() {
$crate::IResult::Incomplete($crate::Needed::Size($tag.len()))
} else if ($i).starts_with($tag) {
$crate::IResult::Done(&$i[$tag.len()..], &$i[0..$tag.len()])
} else {
$crate::IResult::Error(error_position!($crate::ErrorKind::TagStr, $i))
};
res
}
);
);
macro_rules! take_s (
($i:expr, $count:expr) => (
{
let cnt = $count as usize;
let res: $crate::IResult<_,_> = if $i.chars().count() < cnt {
$crate::IResult::Incomplete($crate::Needed::Size(cnt))
} else {
let mut offset = $i.len();
let mut count = 0;
for (o, _) in $i.char_indices() {
if count == cnt {
offset = o;
break;
}
count += 1;
}
$crate::IResult::Done(&$i[offset..], &$i[..offset])
};
res
}
);
);
struct Parser<'a> {
bcd: &'a str,
}
impl<'a> Parser<'a> {
pub fn new() -> Parser<'a> {
Parser{bcd: ""}
}
method!(tag_abc<Parser<'a>, &'a str, &'a str>, self, tag_s!("áβç"));
method!(tag_bcd<Parser<'a> >(&'a str) -> &'a str, self, tag_s!("βçδ"));
method!(pub tag_hij<Parser<'a> >(&'a str) -> &'a str, self, tag_s!("λïJ"));
method!(pub tag_ijk<Parser<'a>, &'a str, &'a str>, self, tag_s!("ïJƙ"));
method!(take3<Parser<'a>, &'a str, &'a str>, self, take_s!(3));
method!(pub simple_call<Parser<'a>, &'a str, &'a str>, mut self,
call_m!(self.tag_abc)
);
method!(pub simple_peek<Parser<'a>, &'a str, &'a str>, mut self,
peek!(call_m!(self.take3))
);
method!(pub simple_chain<Parser<'a>, &'a str, &'a str>, mut self,
do_parse!(
map!(call_m!(self.tag_bcd), |bcd| self.bcd = bcd) >>
last: call_m!(self.simple_peek) >>
(last)
)
);
fn tag_stuff(mut self: Parser<'a>, input: &'a str, something: &'a str) -> (Parser<'a>, ::IResult<&'a str, &'a str>) {
self.bcd = something;
let(tmp, res) = self.tag_abc(input);
self = tmp;
(self, res)
}
method!(use_apply<Parser<'a>, &'a str, &'a str>, mut self, apply_m!(self.tag_stuff, "βçδ"));
}
#[test]
fn test_method_call_abc() {
let p = Parser::new();
let input: &str = "áβçδèƒϱλïJƙ";
let consumed: &str = "áβç";
let leftover: &str = "δèƒϱλïJƙ";
let(_, res) = p.tag_abc(input);
match res {
Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_abc` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.tag_abc` doesnt return the string it consumed \
on success. Expected `{}`, got `{}`.", consumed, output);
},
other => panic!("`Parser.tag_abc` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_method_call_bcd() {
let p = Parser::new();
let input: &str = "βçδèƒϱλïJƙ";
let consumed: &str = "βçδ";
let leftover: &str = "èƒϱλïJƙ";
let(_, res) = p.tag_bcd(input);
match res {
Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_bcd` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.tag_bcd` doesn't return the string it consumed \
on success. Expected `{}`, got `{}`.", consumed, output);
},
other => panic!("`Parser.tag_bcd` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_method_call_hij() {
let p = Parser::new();
let input: &str = "λïJƙℓ₥ñôƥ9řƨ";
let consumed: &str = "λïJ";
let leftover: &str = "ƙℓ₥ñôƥ9řƨ";
let(_, res) = p.tag_hij(input);
match res {
Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_hij` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.tag_hij` doesn't return the string it consumed \
on success. Expected `{}`, got `{}`.", consumed, output);
},
other => panic!("`Parser.tag_hij` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_method_call_ijk() {
let p = Parser::new();
let input: &str = "ïJƙℓ₥ñôƥ9řƨ";
let consumed: &str = "ïJƙ";
let leftover: &str = "ℓ₥ñôƥ9řƨ";
let(_, res) = p.tag_ijk(input);
match res {
Done(extra, output) => { assert!(extra == leftover, "`Parser.tag_ijk` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.tag_ijk` doesn't return the string it consumed \
on success. Expected `{}`, got `{}`.", consumed, output);
},
other => panic!("`Parser.tag_ijk` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_method_simple_call() {
let p = Parser::new();
let input: &str = "áβçδèƒϱλïJƙ";
let consumed: &str = "áβç";
let leftover: &str = "δèƒϱλïJƙ";
let(_, res) = p.simple_call(input);
match res {
Done(extra, output) => { assert!(extra == leftover, "`Parser.simple_call` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.simple_call` doesn't return the string it consumed \
on success. Expected `{}`, got `{}`.", consumed, output);
},
other => panic!("`Parser.simple_call` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_apply_m() {
let mut p = Parser::new();
let input: &str = "áβçδèƒϱλïJƙ";
let consumed: &str = "áβç";
let leftover: &str = "δèƒϱλïJƙ";
let(tmp, res) = p.use_apply(input);
p = tmp;
match res {
Done(extra, output) => { assert!(extra == leftover, "`Parser.use_apply` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.use_apply` doesn't return the string it was supposed to \
on success. Expected `{}`, got `{}`.", leftover, output);
assert!(p.bcd == "βçδ", "Parser.use_apply didn't modify the parser field correctly: {}", p.bcd);
},
other => panic!("`Parser.use_apply` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_method_call_peek() {
let p = Parser::new();
let input: &str = "ж¥ƺáβçδèƒϱλïJƙ";
let consumed: &str = "ж¥ƺ";
let(_, res) = p.simple_peek(input);
match res {
Done(extra, output) => { assert!(extra == input, "`Parser.simple_peek` consumed leftover input. leftover: {}", extra);
assert!(output == consumed, "`Parser.simple_peek` doesn't return the string it consumed \
on success. Expected `{}`, got `{}`.", consumed, output);
},
other => panic!("`Parser.simple_peek` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
#[test]
fn test_method_call_chain() {
let mut p = Parser::new();
let input : &str = "βçδδèƒϱλïJƙℓ";
let leftover : &str = "δèƒϱλïJƙℓ";
let output : &str = "늟";
let(tmp, res) = p.simple_chain(input);
p = tmp;
match res {
Done(extra, out) => { assert!(extra == leftover, "`Parser.simple_chain` consumed leftover input. leftover: {}", extra);
assert!(out == output, "`Parser.simple_chain` doesn't return the string it was supposed to \
on success. Expected `{}`, got `{}`.", output, out);
assert!(p.bcd == "βçδ", "Parser.simple_chain didn't modify the parser field correctly: {}", p.bcd);
},
other => panic!("`Parser.simple_chain` didn't succeed when it should have. \
Got `{:?}`.", other),
}
}
}