#[macro_export]
macro_rules! recognize (
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::HexDisplay;
match $submac!($i, $($args)*) {
$crate::IResult::Done(i,_) => {
let index = ($i).offset(i);
$crate::IResult::Done(i, &($i)[..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))
);
);
#[macro_export]
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)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! tag_bytes (
($i:expr, $bytes: expr) => (
{
let len = $i.len();
let blen = $bytes.len();
let m = if len < blen { len } else { blen };
let reduced = &$i[..m];
let b = &$bytes[..m];
let res: $crate::IResult<_,_> = if reduced != b {
$crate::IResult::Error($crate::Err::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_export]
macro_rules! is_not(
($input:expr, $arr:expr) => (
{
#[inline(always)]
fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
b.as_bytes()
}
let expected = $arr;
let bytes = as_bytes(&expected);
is_not_bytes!($input, bytes)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! is_not_bytes (
($input:expr, $bytes:expr) => (
{
use $crate::InputLength;
let res: $crate::IResult<_,_> = match $input.iter().position(|c| {
for &i in $bytes.iter() {
if *c == i { return true }
}
false
}) {
Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::IsNot,$input)),
Some(n) => {
let res = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done(&$input[$input.input_len()..], $input)
}
};
res
}
);
);
#[macro_export]
macro_rules! is_a (
($input:expr, $arr:expr) => (
{
#[inline(always)]
fn as_bytes<T: $crate::AsBytes>(b: &T) -> &[u8] {
b.as_bytes()
}
let expected = $arr;
let bytes = as_bytes(&expected);
is_a_bytes!($input, bytes)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! is_a_bytes (
($input:expr, $bytes:expr) => (
{
use $crate::InputLength;
let res: $crate::IResult<_,_> = match $input.iter().position(|c| {
for &i in $bytes.iter() {
if *c == i { return false }
}
true
}) {
Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::IsA,$input)),
Some(n) => {
let res: $crate::IResult<_,_> = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done(&$input[($input).input_len()..], $input)
}
};
res
}
);
);
#[macro_export]
macro_rules! escaped (
($i:expr, $submac:ident!( $($args:tt)* ), $control_char: expr, $($rest:tt)+) => (
{
escaped1!($i, $submac!($($args)*), $control_char, $($rest)*)
}
);
($i:expr, $f:expr, $control_char: expr, $($rest:tt)+) => (
escaped1!($i, call!($f), $control_char, $($rest)*)
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! escaped1 (
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
{
escaped_impl!($i, $submac1!($($args)*), $control_char, $submac2!($($args2)*))
}
);
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $g:expr) => (
escaped_impl!($i, $submac1!($($args)*), $control_char, call!($g))
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! escaped_impl (
($i: expr, $normal:ident!( $($args:tt)* ), $control_char: expr, $escapable:ident!( $($args2:tt)* )) => (
{
use $crate::InputLength;
let cl = || {
use $crate::HexDisplay;
let mut index = 0;
while index < $i.len() {
if let $crate::IResult::Done(i,_) = $normal!(&$i[index..], $($args)*) {
if i.is_empty() {
return $crate::IResult::Done(&$i[$i.input_len()..], $i)
} else {
index = $i.offset(i);
}
} else if $i[index] == $control_char as u8 {
if index + 1 >= $i.len() {
return $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Escaped,&$i[index..]));
} else {
match $escapable!(&$i[index+1..], $($args2)*) {
$crate::IResult::Done(i,_) => {
if i.is_empty() {
return $crate::IResult::Done(&$i[$i.input_len()..], $i)
} else {
index = $i.offset(i);
}
},
$crate::IResult::Incomplete(i) => return $crate::IResult::Incomplete(i),
$crate::IResult::Error(e) => return $crate::IResult::Error(e)
}
}
} else {
if index == 0 {
return $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::Escaped,&$i[index..]))
} else {
return $crate::IResult::Done(&$i[index..], &$i[..index])
}
}
}
$crate::IResult::Done(&$i[index..], &$i[..index])
};
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($crate::Err::NodePosition($crate::ErrorKind::Escaped, $i, Box::new(e)))
}
}
}
);
);
#[macro_export]
macro_rules! escaped_transform (
($i:expr, $submac:ident!( $($args:tt)* ), $control_char: expr, $($rest:tt)+) => (
{
escaped_transform1!($i, $submac!($($args)*), $control_char, $($rest)*)
}
);
($i:expr, $f:expr, $control_char: expr, $($rest:tt)+) => (
escaped_transform1!($i, call!($f), $control_char, $($rest)*)
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! escaped_transform1 (
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $submac2:ident!( $($args2:tt)*) ) => (
{
escaped_transform_impl!($i, $submac1!($($args)*), $control_char, $submac2!($($args2)*))
}
);
($i:expr, $submac1:ident!( $($args:tt)* ), $control_char: expr, $g:expr) => (
escaped_transform_impl!($i, $submac1!($($args)*), $control_char, call!($g))
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! escaped_transform_impl (
($i: expr, $normal:ident!( $($args:tt)* ), $control_char: expr, $transform:ident!( $($args2:tt)* )) => (
{
use $crate::InputLength;
let cl = || {
use $crate::HexDisplay;
let mut index = 0;
let mut res = Vec::new();
while index < $i.len() {
if let $crate::IResult::Done(i,o) = $normal!(&$i[index..], $($args)*) {
res.extend(o.iter().cloned());
if i.is_empty() {
return $crate::IResult::Done(&$i[$i.input_len()..], res)
} else {
index = $i.offset(i);
}
} else if $i[index] == $control_char as u8 {
if index + 1 >= $i.len() {
return $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::EscapedTransform,&$i[index..]));
} else {
match $transform!(&$i[index+1..], $($args2)*) {
$crate::IResult::Done(i,o) => {
res.extend(o.iter().cloned());
if i.is_empty() {
return $crate::IResult::Done(&$i[$i.input_len()..], res)
} else {
index = $i.offset(i);
}
},
$crate::IResult::Incomplete(i) => return $crate::IResult::Incomplete(i),
$crate::IResult::Error(e) => return $crate::IResult::Error(e)
}
}
} else {
if index == 0 {
return $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::EscapedTransform,&$i[index..]))
} else {
return $crate::IResult::Done(&$i[index..], res)
}
}
}
$crate::IResult::Done(&$i[index..], res)
};
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($crate::Err::NodePosition($crate::ErrorKind::EscapedTransform, $i, Box::new(e)))
}
}
}
)
);
#[macro_export]
macro_rules! take_while (
($input:expr, $submac:ident!( $($args:tt)* )) => (
{
match $input.iter().position(|c| !$submac!(*c, $($args)*)) {
Some(n) => {
let res:$crate::IResult<_,_> = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done(&$input[($input).len()..], $input)
}
}
}
);
($input:expr, $f:expr) => (
take_while!($input, call!($f));
);
);
#[macro_export]
macro_rules! take_while1 (
($input:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::InputLength;
if ($input).input_len() == 0 {
$crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeWhile1,$input))
} else {
match $input.iter().position(|c| !$submac!(*c, $($args)*)) {
Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeWhile1,$input)),
Some(n) => {
$crate::IResult::Done(&$input[n..], &$input[..n])
},
None => {
$crate::IResult::Done(&$input[($input).len()..], $input)
}
}
}
}
);
($input:expr, $f:expr) => (
take_while1!($input, call!($f));
);
);
#[macro_export]
macro_rules! take_till (
($input:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::InputLength;
match $input.iter().position(|c| $submac!(c, $($args)*)) {
Some(n) => $crate::IResult::Done(&$input[n..], &$input[..n]),
None => $crate::IResult::Done(&$input[($input).input_len()..], $input)
}
}
);
($input:expr, $f:expr) => (
take_till!($input, call!($f));
);
);
#[macro_export]
macro_rules! take (
($i:expr, $count:expr) => (
{
let cnt = $count as usize;
let res: $crate::IResult<_,_> = if $i.len() < cnt {
$crate::IResult::Incomplete($crate::Needed::Size(cnt))
} else {
$crate::IResult::Done(&$i[cnt..],&$i[0..cnt])
};
res
}
);
);
#[macro_export]
macro_rules! take_str (
( $i:expr, $size:expr ) => ( map_res!($i, take!($size), ::std::str::from_utf8) );
);
#[macro_export]
macro_rules! take_until_and_consume(
($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);
take_until_and_consume_bytes!($i, bytes)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! take_until_and_consume_bytes (
($i:expr, $bytes:expr) => (
{
let res: $crate::IResult<_,_> = if $bytes.len() > $i.len() {
$crate::IResult::Incomplete($crate::Needed::Size($bytes.len()))
} else {
let mut index = 0;
let mut parsed = false;
for idx in 0..$i.len() {
if idx + $bytes.len() > $i.len() {
index = idx;
break;
}
if &$i[idx..idx + $bytes.len()] == $bytes {
parsed = true;
index = idx;
break;
}
}
if parsed {
$crate::IResult::Done(&$i[(index + $bytes.len())..], &$i[0..index])
} else {
$crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntilAndConsume,$i))
}
};
res
}
);
);
#[macro_export]
macro_rules! take_until(
($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);
take_until_bytes!($i, bytes)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! take_until_bytes(
($i:expr, $bytes:expr) => (
{
let res: $crate::IResult<_,_> = if $bytes.len() > $i.len() {
$crate::IResult::Incomplete($crate::Needed::Size($bytes.len()))
} else {
let mut index = 0;
let mut parsed = false;
for idx in 0..$i.len() {
if idx + $bytes.len() > $i.len() {
index = idx;
break;
}
if &$i[idx..idx+$bytes.len()] == $bytes {
parsed = true;
index = idx;
break;
}
}
if parsed {
$crate::IResult::Done(&$i[index..], &$i[0..index])
} else {
$crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntil,$i))
}
};
res
}
);
);
#[macro_export]
macro_rules! take_until_either_and_consume(
($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);
take_until_either_and_consume_bytes!($i, bytes)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! take_until_either_and_consume_bytes(
($i:expr, $bytes:expr) => (
{
let res: $crate::IResult<_,_> = if 1 > $i.len() {
$crate::IResult::Incomplete($crate::Needed::Size(1))
} else {
let mut index = 0;
let mut parsed = false;
for idx in 0..$i.len() {
if idx + 1 > $i.len() {
index = idx;
break;
}
for &t in $bytes.iter() {
if $i[idx] == t {
parsed = true;
index = idx;
break;
}
}
if parsed { break; }
}
if parsed {
$crate::IResult::Done(&$i[(index+1)..], &$i[0..index])
} else {
$crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntilEitherAndConsume,$i))
}
};
res
}
);
);
#[macro_export]
macro_rules! take_until_either(
($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);
take_until_either_bytes!($i, bytes)
}
);
);
#[doc(hidden)]
#[macro_export]
macro_rules! take_until_either_bytes(
($i:expr, $bytes:expr) => (
{
let res: $crate::IResult<_,_> = if 1 > $i.len() {
$crate::IResult::Incomplete($crate::Needed::Size(1))
} else {
let mut index = 0;
let mut parsed = false;
for idx in 0..$i.len() {
if idx + 1 > $i.len() {
index = idx;
break;
}
for &t in $bytes.iter() {
if $i[idx] == t {
parsed = true;
index = idx;
break;
}
}
if parsed { break; }
}
if parsed {
$crate::IResult::Done(&$i[index..], &$i[0..index])
} else {
$crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeUntilEither,$i))
}
};
res
}
);
);
#[macro_export]
macro_rules! length_bytes(
($i:expr, $submac:ident!( $($args:tt)* )) => (
{
match $submac!($i, $($args)*) {
$crate::IResult::Error(a) => $crate::IResult::Error(a),
$crate::IResult::Incomplete(i) => $crate::IResult::Incomplete(i),
$crate::IResult::Done(i1,nb) => {
let nb = nb as usize;
let length_remaining = i1.len();
if length_remaining < nb {
$crate::IResult::Incomplete($crate::Needed::Size(nb - length_remaining))
} else {
$crate::IResult::Done(&i1[nb..], &i1[..nb])
}
}
}
}
);
($i:expr, $f:expr) => (
length_bytes!($i, call!($f))
)
);
#[cfg(test)]
mod tests {
use internal::Needed;
use internal::IResult::*;
use internal::Err::*;
use util::ErrorKind;
use nom::{alpha, digit, hex_digit, oct_digit, alphanumeric, space, multispace};
#[test]
fn is_a() {
named!(a_or_b, is_a!(&b"ab"[..]));
let a = &b"abcd"[..];
assert_eq!(a_or_b(a), Done(&b"cd"[..], &b"ab"[..]));
let b = &b"bcde"[..];
assert_eq!(a_or_b(b), Done(&b"cde"[..], &b"b"[..]));
let c = &b"cdef"[..];
assert_eq!(a_or_b(c), Error(Position(ErrorKind::IsA,c)));
let d = &b"bacdef"[..];
assert_eq!(a_or_b(d), Done(&b"cdef"[..], &b"ba"[..]));
}
#[test]
fn is_not() {
named!(a_or_b, is_not!(&b"ab"[..]));
let a = &b"cdab"[..];
assert_eq!(a_or_b(a), Done(&b"ab"[..], &b"cd"[..]));
let b = &b"cbde"[..];
assert_eq!(a_or_b(b), Done(&b"bde"[..], &b"c"[..]));
let c = &b"abab"[..];
assert_eq!(a_or_b(c), Error(Position(ErrorKind::IsNot,c)));
let d = &b"cdefba"[..];
assert_eq!(a_or_b(d), Done(&b"ba"[..], &b"cdef"[..]));
let e = &b"e"[..];
assert_eq!(a_or_b(e), Done(&b""[..], &b"e"[..]));
let f = &b"fghi"[..];
assert_eq!(a_or_b(f), Done(&b""[..], &b"fghi"[..]));
}
#[test]
fn escaping() {
named!(esc, escaped!(call!(alpha), '\\', is_a_bytes!(&b"\"n\\"[..])));
assert_eq!(esc(&b"abcd"[..]), Done(&b""[..], &b"abcd"[..]));
assert_eq!(esc(&b"ab\\\"cd"[..]), Done(&b""[..], &b"ab\\\"cd"[..]));
assert_eq!(esc(&b"\\\"abcd"[..]), Done(&b""[..], &b"\\\"abcd"[..]));
assert_eq!(esc(&b"\\n"[..]), Done(&b""[..], &b"\\n"[..]));
assert_eq!(esc(&b"ab\\\"12"[..]), Done(&b"12"[..], &b"ab\\\""[..]));
assert_eq!(esc(&b"AB\\"[..]), Error(NodePosition(ErrorKind::Escaped, &b"AB\\"[..], Box::new(Position(ErrorKind::Escaped, &b"\\"[..])))));
assert_eq!(esc(&b"AB\\A"[..]), Error(NodePosition(ErrorKind::Escaped, &b"AB\\A"[..], Box::new(Position(ErrorKind::IsA, &b"A"[..])))));
}
fn to_s(i:Vec<u8>) -> String {
String::from_utf8_lossy(&i).into_owned()
}
#[test]
fn escape_transform() {
use std::str;
named!(esc< String >, map!(escaped_transform!(alpha, '\\',
alt!(
tag!("\\") => { |_| &b"\\"[..] }
| tag!("\"") => { |_| &b"\""[..] }
| tag!("n") => { |_| &b"\n"[..] }
)), to_s)
);
assert_eq!(esc(&b"abcd"[..]), Done(&b""[..], String::from("abcd")));
assert_eq!(esc(&b"ab\\\"cd"[..]), Done(&b""[..], String::from("ab\"cd")));
assert_eq!(esc(&b"\\\"abcd"[..]), Done(&b""[..], String::from("\"abcd")));
assert_eq!(esc(&b"\\n"[..]), Done(&b""[..], String::from("\n")));
assert_eq!(esc(&b"ab\\\"12"[..]), Done(&b"12"[..], String::from("ab\"")));
assert_eq!(esc(&b"AB\\"[..]), Error(NodePosition(ErrorKind::EscapedTransform, &b"AB\\"[..], Box::new(Position(ErrorKind::EscapedTransform, &b"\\"[..])))));
assert_eq!(esc(&b"AB\\A"[..]), Error(NodePosition(ErrorKind::EscapedTransform, &b"AB\\A"[..], Box::new(Position(ErrorKind::Alt, &b"A"[..])))));
let e = "è";
let a = "Ã ";
println!("è: {:?} | à : {:?}", str::as_bytes(e), str::as_bytes(a));
named!(esc2< String >, map!(escaped_transform!(call!(alpha), '&',
alt!(
tag!("egrave;") => { |_| str::as_bytes("è") }
| tag!("agrave;") => { |_| str::as_bytes("Ã ") }
)), to_s)
);
assert_eq!(esc2(&b"abèDEF"[..]), Done(&b""[..], String::from("abèDEF")));
assert_eq!(esc2(&b"abèDàEF"[..]), Done(&b""[..], String::from("abèDà EF")));
}
#[test]
fn issue_84() {
let r0 = is_a!(&b"aaaaefgh"[..], "abcd");
assert_eq!(r0, Done(&b"efgh"[..], &b"aaaa"[..]));
let r1 = is_a!(&b"aaaa"[..], "abcd");
assert_eq!(r1, Done(&b""[..], &b"aaaa"[..]));
let r2 = is_a!(&b"1"[..], "123456789");
assert_eq!(r2, Done(&b""[..], &b"1"[..]));
}
#[test]
fn take_str_test() {
let a = b"omnomnom";
assert_eq!(take_str!(&a[..], 5), Done(&b"nom"[..], "omnom"));
assert_eq!(take_str!(&a[..], 9), Incomplete(Needed::Size(9)));
}
#[test]
fn take_until_test() {
named!(x, take_until_and_consume!("efgh"));
let r = x(&b"abcdabcdefghijkl"[..]);
assert_eq!(r, Done(&b"ijkl"[..], &b"abcdabcd"[..]));
println!("Done 1\n");
let r2 = x(&b"abcdabcdefgh"[..]);
assert_eq!(r2, Done(&b""[..], &b"abcdabcd"[..]));
println!("Done 2\n");
let r3 = x(&b"abcefg"[..]);
assert_eq!(r3, Error(Position(ErrorKind::TakeUntilAndConsume, &b"abcefg"[..])));
assert_eq!(
x(&b"ab"[..]),
Incomplete(Needed::Size(4))
);
}
#[test]
fn take_until_either_incomplete() {
named!(x, take_until_either!("!."));
assert_eq!(
x(&b"123"[..]),
Error(Position(ErrorKind::TakeUntilEither, &b"123"[..]))
);
}
#[test]
fn take_until_incomplete() {
named!(y, take_until!("end"));
assert_eq!(
y(&b"nd"[..]),
Incomplete(Needed::Size(3))
);
assert_eq!(
y(&b"123"[..]),
Error(Position(ErrorKind::TakeUntil, &b"123"[..]))
);
}
#[test]
fn recognize() {
named!(x, recognize!(delimited!(tag!("<!--"), take!(5), tag!("-->"))));
let r = x(&b"<!-- abc --> aaa"[..]);
assert_eq!(r, Done(&b" aaa"[..], &b"<!-- abc -->"[..]));
let empty = &b""[..];
named!(ya, recognize!(alpha));
let ra = ya(&b"abc"[..]);
assert_eq!(ra, Done(empty, &b"abc"[..]));
named!(yd, recognize!(digit));
let rd = yd(&b"123"[..]);
assert_eq!(rd, Done(empty, &b"123"[..]));
named!(yhd, recognize!(hex_digit));
let rhd = yhd(&b"123abcDEF"[..]);
assert_eq!(rhd, Done(empty, &b"123abcDEF"[..]));
named!(yod, recognize!(oct_digit));
let rod = yod(&b"1234567"[..]);
assert_eq!(rod, Done(empty, &b"1234567"[..]));
named!(yan, recognize!(alphanumeric));
let ran = yan(&b"123abc"[..]);
assert_eq!(ran, Done(empty, &b"123abc"[..]));
named!(ys, recognize!(space));
let rs = ys(&b" \t"[..]);
assert_eq!(rs, Done(empty, &b" \t"[..]));
named!(yms, recognize!(multispace));
let rms = yms(&b" \t\r\n"[..]);
assert_eq!(rms, Done(empty, &b" \t\r\n"[..]));
}
#[test]
fn take_while() {
use nom::is_alphabetic;
named!(f, take_while!(is_alphabetic));
let a = b"";
let b = b"abcd";
let c = b"abcd123";
let d = b"123";
assert_eq!(f(&a[..]), Done(&a[..], &a[..]));
assert_eq!(f(&b[..]), Done(&a[..], &b[..]));
assert_eq!(f(&c[..]), Done(&d[..], &b[..]));
assert_eq!(f(&d[..]), Done(&d[..], &a[..]));
}
#[test]
fn take_while1() {
use nom::is_alphabetic;
named!(f, take_while1!(is_alphabetic));
let a = b"";
let b = b"abcd";
let c = b"abcd123";
let d = b"123";
assert_eq!(f(&a[..]), Error(Position(ErrorKind::TakeWhile1, &b""[..])));
assert_eq!(f(&b[..]), Done(&a[..], &b[..]));
assert_eq!(f(&c[..]), Done(&b"123"[..], &b[..]));
assert_eq!(f(&d[..]), Error(Position(ErrorKind::TakeWhile1, &d[..])));
}
#[cfg(feature = "nightly")]
use test::Bencher;
#[cfg(feature = "nightly")]
#[bench]
fn take_while_bench(b: &mut Bencher) {
use nom::is_alphabetic;
named!(f, take_while!(is_alphabetic));
b.iter(|| {
f(&b"abcdefghijklABCDEejfrfrjgro12aa"[..])
});
}
#[test]
fn recognize_take_while() {
use nom::is_alphanumeric;
named!(x, take_while!(is_alphanumeric));
named!(y, recognize!(x));
assert_eq!(x(&b"ab"[..]), Done(&[][..], &b"ab"[..]));
println!("X: {:?}", x(&b"ab"[..]));
assert_eq!(y(&b"ab"[..]), Done(&[][..], &b"ab"[..]));
}
}