#[allow(unused_variables)]
#[macro_export]
macro_rules! closure (
($ty:ty, $submac:ident!( $($args:tt)* )) => (
|i: $ty| { $submac!(i, $($args)*) }
);
($submac:ident!( $($args:tt)* )) => (
|i| { $submac!(i, $($args)*) }
);
);
#[macro_export]
macro_rules! named (
(#$($args:tt)*) => (
named_attr!(#$($args)*);
);
($name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( i: $i ) -> $crate::IResult<$i,$o,u32> {
$submac!(i, $($args)*)
}
);
($name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
$submac!(i, $($args)*)
}
);
($name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
$submac!(i, $($args)*)
}
);
($name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name<'a>( i: &'a[u8] ) -> $crate::IResult<&'a [u8], $o, u32> {
$submac!(i, $($args)*)
}
);
($name:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
fn $name( i: &[u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
$submac!(i, $($args)*)
}
);
(pub $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( i: $i ) -> $crate::IResult<$i,$o, u32> {
$submac!(i, $($args)*)
}
);
(pub $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
$submac!(i, $($args)*)
}
);
(pub $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
$submac!(i, $($args)*)
}
);
(pub $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name( i: &[u8] ) -> $crate::IResult<&[u8], $o, u32> {
$submac!(i, $($args)*)
}
);
(pub $name:ident, $submac:ident!( $($args:tt)* )) => (
#[allow(unused_variables)]
pub fn $name<'a>( i: &'a [u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
$submac!(i, $($args)*)
}
);
);
#[macro_export]
macro_rules! named_args {
(pub $func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
pub fn $func_name(input: &[u8], $( $arg : $typ ),*) -> $crate::IResult<&[u8], $return_type> {
$submac!(input, $($args)*)
}
};
(pub $func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
pub fn $func_name<'a>(input: &'a [u8], $( $arg : $typ ),*) -> $crate::IResult<&'a [u8], $return_type> {
$submac!(input, $($args)*)
}
};
($func_name:ident ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
fn $func_name(input: &[u8], $( $arg : $typ ),*) -> $crate::IResult<&[u8], $return_type> {
$submac!(input, $($args)*)
}
};
($func_name:ident < 'a > ( $( $arg:ident : $typ:ty ),* ) < $return_type:ty > , $submac:ident!( $($args:tt)* ) ) => {
fn $func_name<'a>(input: &'a [u8], $( $arg : $typ ),*) -> $crate::IResult<&'a [u8], $return_type> {
$submac!(input, $($args)*)
}
};
}
#[macro_export]
macro_rules! named_attr (
($(#[$attr:meta])*, $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
fn $name( i: $i ) -> $crate::IResult<$i,$o,u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
fn $name<'a>( i: &'a[u8] ) -> $crate::IResult<&'a [u8], $o, u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, $name:ident, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
fn $name( i: &[u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, pub $name:ident( $i:ty ) -> $o:ty, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
pub fn $name( i: $i ) -> $crate::IResult<$i,$o, u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, pub $name:ident<$i:ty,$o:ty,$e:ty>, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
pub fn $name( i: $i ) -> $crate::IResult<$i, $o, $e> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, pub $name:ident<$i:ty,$o:ty>, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
pub fn $name( i: $i ) -> $crate::IResult<$i, $o, u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, pub $name:ident<$o:ty>, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
pub fn $name( i: &[u8] ) -> $crate::IResult<&[u8], $o, u32> {
$submac!(i, $($args)*)
}
);
($(#[$attr:meta])*, pub $name:ident, $submac:ident!( $($args:tt)* )) => (
$(#[$attr])*
pub fn $name<'a>( i: &'a [u8] ) -> $crate::IResult<&[u8], &[u8], u32> {
$submac!(i, $($args)*)
}
);
);
#[macro_export]
macro_rules! call (
($i:expr, $fun:expr) => ( $fun( $i ) );
($i:expr, $fun:expr, $($args:expr),* ) => ( $fun( $i, $($args),* ) );
);
#[macro_export]
macro_rules! apply (
($i:expr, $fun:expr, $($args:expr),* ) => ( $fun( $i, $($args),* ) );
);
#[macro_export]
macro_rules! return_error (
($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
{
let cl = || {
$submac!($i, $($args)*)
};
match cl() {
$crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
$crate::IResult::Done(i, o) => $crate::IResult::Done(i, o),
$crate::IResult::Error(e) => {
return $crate::IResult::Error(error_node_position!($code, $i, e))
}
}
}
);
($i:expr, $code:expr, $f:expr) => (
return_error!($i, $code, call!($f));
);
);
#[macro_export]
macro_rules! add_return_error (
($i:expr, $code:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Incomplete(x) => $crate::IResult::Incomplete(x),
$crate::IResult::Done(i, o) => $crate::IResult::Done(i, o),
$crate::IResult::Error(e) => {
$crate::IResult::Error(error_node_position!($code, $i, e))
}
}
}
);
($i:expr, $code:expr, $f:expr) => (
add_return_error!($i, $code, call!($f));
);
);
#[macro_export]
macro_rules! complete (
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Done(i, o) => $crate::IResult::Done(i, o),
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete(_) => {
$crate::IResult::Error(error_position!($crate::ErrorKind::Complete, $i))
},
}
}
);
($i:expr, $f:expr) => (
complete!($i, call!($f));
);
);
#[macro_export]
macro_rules! try_parse (
($i:expr, $submac:ident!( $($args:tt)* )) => (
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => (i,o),
$crate::IResult::Error(e) => return $crate::IResult::Error(e),
$crate::IResult::Incomplete(i) => return $crate::IResult::Incomplete(i)
}
);
($i:expr, $f:expr) => (
try_parse!($i, call!($f))
);
);
#[macro_export]
macro_rules! map(
(__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
$crate::IResult::Incomplete($crate::Needed::Size(i)) => $crate::IResult::Incomplete($crate::Needed::Size(i)),
$crate::IResult::Done(i, o) => $crate::IResult::Done(i, $submac2!(o, $($args2)*))
}
}
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
map!(__impl $i, $submac!($($args)*), call!($g));
);
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
map!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
);
($i:expr, $f:expr, $g:expr) => (
map!(__impl $i, call!($f), call!($g));
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
map!(__impl $i, call!($f), $submac!($($args)*));
);
);
#[macro_export]
macro_rules! map_res (
(__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
$crate::IResult::Incomplete($crate::Needed::Size(i)) => $crate::IResult::Incomplete($crate::Needed::Size(i)),
$crate::IResult::Done(i, o) => match $submac2!(o, $($args2)*) {
Ok(output) => $crate::IResult::Done(i, output),
Err(_) => $crate::IResult::Error(error_position!($crate::ErrorKind::MapRes, $i))
}
}
}
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
map_res!(__impl $i, $submac!($($args)*), call!($g));
);
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
map_res!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
);
($i:expr, $f:expr, $g:expr) => (
map_res!(__impl $i, call!($f), call!($g));
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
map_res!(__impl $i, call!($f), $submac!($($args)*));
);
);
#[macro_export]
macro_rules! map_opt (
(__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
$crate::IResult::Incomplete($crate::Needed::Size(i)) => $crate::IResult::Incomplete($crate::Needed::Size(i)),
$crate::IResult::Done(i, o) => match $submac2!(o, $($args2)*) {
::std::option::Option::Some(output) => $crate::IResult::Done(i, output),
::std::option::Option::None => $crate::IResult::Error(error_position!($crate::ErrorKind::MapOpt, $i))
}
}
}
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
map_opt!(__impl $i, $submac!($($args)*), call!($g));
);
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
map_opt!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
);
($i:expr, $f:expr, $g:expr) => (
map_opt!(__impl $i, call!($f), call!($g));
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
map_opt!(__impl $i, call!($f), $submac!($($args)*));
);
);
#[macro_export]
macro_rules! parse_to (
($i:expr, $t:ty ) => (
{
use $crate::ParseTo;
use $crate::InputLength;
match ($i).parse_to() {
::std::option::Option::Some(output) => $crate::IResult::Done($i.slice(..$i.input_len()), output),
::std::option::Option::None => $crate::IResult::Error(error_position!($crate::ErrorKind::MapOpt, $i))
}
}
);
);
#[macro_export]
macro_rules! verify (
(__impl $i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete($crate::Needed::Unknown) => $crate::IResult::Incomplete($crate::Needed::Unknown),
$crate::IResult::Incomplete($crate::Needed::Size(i)) => $crate::IResult::Incomplete($crate::Needed::Size(i)),
$crate::IResult::Done(i, o) => if $submac2!(o, $($args2)*) {
$crate::IResult::Done(i, o)
} else {
$crate::IResult::Error(error_position!($crate::ErrorKind::Verify, $i))
}
}
}
);
($i:expr, $submac:ident!( $($args:tt)* ), $g:expr) => (
verify!(__impl $i, $submac!($($args)*), call!($g));
);
($i:expr, $submac:ident!( $($args:tt)* ), $submac2:ident!( $($args2:tt)* )) => (
verify!(__impl $i, $submac!($($args)*), $submac2!($($args2)*));
);
($i:expr, $f:expr, $g:expr) => (
verify!(__impl $i, call!($f), call!($g));
);
($i:expr, $f:expr, $submac:ident!( $($args:tt)* )) => (
verify!(__impl $i, call!($f), $submac!($($args)*));
);
);
#[macro_export]
macro_rules! value (
($i:expr, $res:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,_) => {
$crate::IResult::Done(i, $res)
},
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
}
);
($i:expr, $res:expr, $f:expr) => (
value!($i, $res, call!($f))
);
($i:expr, $res:expr) => (
$crate::IResult::Done($i, $res)
);
);
#[macro_export]
macro_rules! expr_res (
($i:expr, $e:expr) => (
{
match $e {
Ok(output) => $crate::IResult::Done($i, output),
Err(_) => $crate::IResult::Error(error_position!($crate::ErrorKind::ExprRes, $i))
}
}
);
);
#[macro_export]
macro_rules! expr_opt (
($i:expr, $e:expr) => (
{
match $e {
::std::option::Option::Some(output) => $crate::IResult::Done($i, output),
::std::option::Option::None => $crate::IResult::Error(error_position!($crate::ErrorKind::ExprOpt, $i))
}
}
);
);
#[macro_export]
macro_rules! opt(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => $crate::IResult::Done(i, ::std::option::Option::Some(o)),
$crate::IResult::Error(_) => $crate::IResult::Done($i, ::std::option::Option::None),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
}
);
($i:expr, $f:expr) => (
opt!($i, call!($f));
);
);
#[macro_export]
macro_rules! opt_res (
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => $crate::IResult::Done(i, ::std::result::Result::Ok(o)),
$crate::IResult::Error(e) => $crate::IResult::Done($i, ::std::result::Result::Err(e)),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
}
);
($i:expr, $f:expr) => (
opt_res!($i, call!($f));
);
);
#[macro_export]
macro_rules! cond_with_error(
($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
{
if $cond {
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => $crate::IResult::Done(i, ::std::option::Option::Some(o)),
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
} else {
$crate::IResult::Done($i, ::std::option::Option::None)
}
}
);
($i:expr, $cond:expr, $f:expr) => (
cond_with_error!($i, $cond, call!($f));
);
);
#[macro_export]
macro_rules! cond(
($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
{
if $cond {
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => $crate::IResult::Done(i, ::std::option::Option::Some(o)),
$crate::IResult::Error(_) => $crate::IResult::Done($i, ::std::option::Option::None),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
} else {
$crate::IResult::Done($i, ::std::option::Option::None)
}
}
);
($i:expr, $cond:expr, $f:expr) => (
cond!($i, $cond, call!($f));
);
);
#[macro_export]
macro_rules! cond_reduce(
($i:expr, $cond:expr, $submac:ident!( $($args:tt)* )) => (
{
if $cond {
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => $crate::IResult::Done(i, o),
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
} else {
$crate::IResult::Error(error_position!($crate::ErrorKind::CondReduce, $i))
}
}
);
($i:expr, $cond:expr, $f:expr) => (
cond_reduce!($i, $cond, call!($f));
);
);
#[macro_export]
macro_rules! peek(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Done(_,o) => $crate::IResult::Done($i, o),
$crate::IResult::Error(a) => $crate::IResult::Error(a),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
}
);
($i:expr, $f:expr) => (
peek!($i, call!($f));
);
);
#[macro_export]
macro_rules! not(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::Slice;
match $submac!($i, $($args)*) {
$crate::IResult::Done(_, _) => $crate::IResult::Error(error_position!($crate::ErrorKind::Not, $i)),
$crate::IResult::Error(_) => $crate::IResult::Done($i, ($i).slice(..0)),
$crate::IResult::Incomplete(_) => $crate::IResult::Done($i, ($i).slice(..0))
}
}
);
($i:expr, $f:expr) => (
not!($i, call!($f));
);
);
#[macro_export]
macro_rules! tap (
($i:expr, $name:ident : $submac:ident!( $($args:tt)* ) => $e:expr) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,o) => {
let $name = o;
$e;
$crate::IResult::Done(i, $name)
},
$crate::IResult::Error(a) => $crate::IResult::Error(a),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
}
);
($i:expr, $name: ident: $f:expr => $e:expr) => (
tap!($i, $name: call!($f) => $e);
);
);
#[macro_export]
macro_rules! eof (
($i:expr,) => (
{
use $crate::InputLength;
if ($i).input_len() == 0 {
$crate::IResult::Done($i, $i)
} else {
$crate::IResult::Error(error_position!($crate::ErrorKind::Eof, $i))
}
}
);
);
#[macro_export]
macro_rules! recognize (
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::Offset;
use $crate::Slice;
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,_) => {
let index = ($i).offset(i);
$crate::IResult::Done(i, ($i).slice(..index))
},
$crate::IResult::Error(e) => $crate::IResult::Error(e),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i)
}
}
);
($i:expr, $f:expr) => (
recognize!($i, call!($f))
);
);
#[cfg(test)]
mod tests {
use internal::{Needed,IResult};
#[cfg(feature = "verbose-errors")]
use verbose_errors::Err;
#[cfg(not(feature = "verbose-errors"))]
use simple_errors::Err;
use internal::IResult::*;
use util::ErrorKind;
macro_rules! tag (
($i:expr, $inp: expr) => (
{
#[inline(always)]
fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
b.as_bytes()
}
let expected = $inp;
let bytes = as_bytes(&expected);
tag_bytes!($i,bytes)
}
);
);
macro_rules! tag_bytes (
($i:expr, $bytes: expr) => (
{
use std::cmp::min;
let len = $i.len();
let blen = $bytes.len();
let m = min(len, blen);
let reduced = &$i[..m];
let b = &$bytes[..m];
let res: $crate::IResult<_,_> = if reduced != b {
$crate::IResult::Error(error_position!($crate::ErrorKind::Tag, $i))
} else if m < blen {
$crate::IResult::Incomplete($crate::Needed::Size(blen))
} else {
$crate::IResult::Done(&$i[blen..], reduced)
};
res
}
);
);
macro_rules! take(
($i:expr, $count:expr) => (
{
let cnt = $count as usize;
let res:$crate::IResult<&[u8],&[u8]> = if $i.len() < cnt {
$crate::IResult::Incomplete($crate::Needed::Size(cnt))
} else {
$crate::IResult::Done(&$i[cnt..],&$i[0..cnt])
};
res
}
);
);
mod pub_named_mod {
named!(pub tst, tag!("abcd"));
}
#[test]
fn pub_named_test() {
let a = &b"abcd"[..];
let res = pub_named_mod::tst(a);
assert_eq!(res, Done(&b""[..], a));
}
#[test]
fn apply_test() {
fn sum2(a:u8, b:u8) -> u8 { a + b }
fn sum3(a:u8, b:u8, c:u8) -> u8 { a + b + c }
let a = apply!(1, sum2, 2);
let b = apply!(1, sum3, 2, 3);
assert_eq!(a, 3);
assert_eq!(b, 6);
}
#[test]
fn opt() {
named!(opt_abcd<&[u8],Option<&[u8]> >, opt!(tag!("abcd")));
let a = &b"abcdef"[..];
let b = &b"bcdefg"[..];
let c = &b"ab"[..];
assert_eq!(opt_abcd(a), Done(&b"ef"[..], Some(&b"abcd"[..])));
assert_eq!(opt_abcd(b), Done(&b"bcdefg"[..], None));
assert_eq!(opt_abcd(c), Incomplete(Needed::Size(4)));
}
#[cfg(feature = "verbose-errors")]
#[test]
fn opt_res() {
named!(opt_res_abcd<&[u8], Result<&[u8], Err<&[u8]> > >, opt_res!(tag!("abcd")));
let a = &b"abcdef"[..];
let b = &b"bcdefg"[..];
let c = &b"ab"[..];
assert_eq!(opt_res_abcd(a), Done(&b"ef"[..], Ok(&b"abcd"[..])));
assert_eq!(opt_res_abcd(b), Done(&b"bcdefg"[..], Err(error_position!(ErrorKind::Tag, b))));
assert_eq!(opt_res_abcd(c), Incomplete(Needed::Size(4)));
}
#[cfg(not(feature = "verbose-errors"))]
#[test]
fn opt_res() {
named!(opt_res_abcd<&[u8], Result<&[u8], Err<u32>> >, opt_res!(tag!("abcd")));
let a = &b"abcdef"[..];
let b = &b"bcdefg"[..];
let c = &b"ab"[..];
assert_eq!(opt_res_abcd(a), Done(&b"ef"[..], Ok(&b"abcd"[..])));
assert_eq!(opt_res_abcd(b), Done(&b"bcdefg"[..], Err(error_position!(ErrorKind::Tag, b))));
assert_eq!(opt_res_abcd(c), Incomplete(Needed::Size(4)));
}
#[test]
fn cond() {
let f_true: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( true, tag!("abcd") ) ));
let f_false: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( false, tag!("abcd") ) ));
assert_eq!(f_true(&b"abcdef"[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
assert_eq!(f_true(&b"ab"[..]), Incomplete(Needed::Size(4)));
assert_eq!(f_true(&b"xxx"[..]), Done(&b"xxx"[..], None));
assert_eq!(f_false(&b"abcdef"[..]), Done(&b"abcdef"[..], None));
assert_eq!(f_false(&b"ab"[..]), Done(&b"ab"[..], None));
assert_eq!(f_false(&b"xxx"[..]), Done(&b"xxx"[..], None));
}
#[test]
fn cond_wrapping() {
named!( tag_abcd, tag!("abcd") );
let f_true: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( true, tag_abcd ) ));
let f_false: Box<Fn(&'static [u8]) -> IResult<&[u8],Option<&[u8]>, &str>> = Box::new(closure!(&'static [u8], cond!( false, tag_abcd ) ));
assert_eq!(f_true(&b"abcdef"[..]), Done(&b"ef"[..], Some(&b"abcd"[..])));
assert_eq!(f_true(&b"ab"[..]), Incomplete(Needed::Size(4)));
assert_eq!(f_true(&b"xxx"[..]), Done(&b"xxx"[..], None));
assert_eq!(f_false(&b"abcdef"[..]), Done(&b"abcdef"[..], None));
assert_eq!(f_false(&b"ab"[..]), Done(&b"ab"[..], None));
assert_eq!(f_false(&b"xxx"[..]), Done(&b"xxx"[..], None));
}
#[test]
fn peek() {
named!(peek_tag<&[u8],&[u8]>, peek!(tag!("abcd")));
assert_eq!(peek_tag(&b"abcdef"[..]), Done(&b"abcdef"[..], &b"abcd"[..]));
assert_eq!(peek_tag(&b"ab"[..]), Incomplete(Needed::Size(4)));
assert_eq!(peek_tag(&b"xxx"[..]), Error(error_position!(ErrorKind::Tag, &b"xxx"[..])));
}
#[test]
fn not() {
named!(not_aaa, not!(tag!("aaa")));
assert_eq!(not_aaa(&b"aaa"[..]), Error(error_position!(ErrorKind::Not, &b"aaa"[..])));
assert_eq!(not_aaa(&b"aa"[..]), Done(&b"aa"[..], &b""[..]));
assert_eq!(not_aaa(&b"abcd"[..]), Done(&b"abcd"[..], &b""[..]));
}
#[test]
fn verify() {
named!(test, verify!(take!(5), |slice: &[u8]| slice[0] == 'a' as u8));
assert_eq!(test(&b"bcd"[..]), Incomplete(Needed::Size(5)));
assert_eq!(test(&b"bcdefg"[..]), Error(error_position!(ErrorKind::Verify, &b"bcdefg"[..])));
assert_eq!(test(&b"abcdefg"[..]), Done(&b"fg"[..], &b"abcde"[..]));
}
}