#[macro_export]
macro_rules! tag_s (
($i:expr, $tag: expr) => (
{
let res: $crate::IResult<&str,&str> = 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($crate::Err::Position($crate::ErrorKind::TagStr, $i))
};
res
}
);
);
#[macro_export]
macro_rules! take_s (
($i:expr, $count:expr) => (
{
let cnt = $count as usize;
let res: $crate::IResult<&str,&str> = 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! is_not_s (
($input:expr, $arr:expr) => (
{
let res: $crate::IResult<&str,&str> = match $input.chars().position(|c| {
for i in $arr.chars() {
if c == i { return true }
}
false
}) {
Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::IsNotStr,$input)),
Some(n) => {
let res = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done("", $input)
}
};
res
}
);
);
#[macro_export]
macro_rules! is_a_s (
($input:expr, $arr:expr) => (
{
let res: $crate::IResult<&str,&str> = match $input.chars().position(|c| {
for i in $arr.chars() {
if c == i { return false }
}
true
}) {
Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::IsAStr,$input)),
Some(n) => {
let res: $crate::IResult<&str,&str> = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done("", $input)
}
};
res
}
);
);
#[macro_export]
macro_rules! take_while_s (
($input:expr, $submac:ident!( $($args:tt)* )) => (
{
match $input.chars().position(|c| !$submac!(c, $($args)*)) {
Some(n) => {
let res = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done("", $input)
}
}
}
);
($input:expr, $f:expr) => (
take_while_s!($input, call!($f));
);
);
#[macro_export]
macro_rules! take_while1_s (
($input:expr, $submac:ident!( $($args:tt)* )) => (
{
use $crate::InputLength;
if ($input).input_len() == 0 {
$crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeWhile1Str,$input))
} else {
match $input.chars().position(|c| !$submac!(c, $($args)*)) {
Some(0) => $crate::IResult::Error($crate::Err::Position($crate::ErrorKind::TakeWhile1Str,$input)),
Some(n) => {
let res = $crate::IResult::Done(&$input[n..], &$input[..n]);
res
},
None => {
$crate::IResult::Done("", $input)
}
}
}
}
);
($input:expr, $f:expr) => (
take_while1_s!($input, call!($f));
);
);
#[macro_export]
macro_rules! take_till_s (
($input:expr, $submac:ident!( $($args:tt)* )) => (
{
match $input.chars().position(|c| $submac!(c, $($args)*)) {
Some(n) => $crate::IResult::Done(&$input[n..], &$input[..n]),
None => $crate::IResult::Done("", $input)
}
}
);
($input:expr, $f:expr) => (
take_till_s!($input, call!($f));
);
);
#[cfg(test)]
mod test {
use ::IResult;
#[test]
fn tag_str_succeed() {
const INPUT: &'static str = "Hello World!";
const TAG: &'static str = "Hello";
fn test(input: &str) -> IResult<&str, &str> {
tag_s!(input, TAG)
}
match test(INPUT) {
IResult::Done(extra, output) => {
assert!(extra == " World!", "Parser `tag_s` consumed leftover input.");
assert!(output == TAG,
"Parser `tag_s` doesn't return the tag it matched on success. \
Expected `{}`, got `{}`.", TAG, output);
},
other => panic!("Parser `tag_s` didn't succeed when it should have. \
Got `{:?}`.", other),
};
}
#[test]
fn tag_str_incomplete() {
const INPUT: &'static str = "Hello";
const TAG: &'static str = "Hello World!";
match tag_s!(INPUT, TAG) {
IResult::Incomplete(_) => (),
other => {
panic!("Parser `tag_s` didn't require more input when it should have. \
Got `{:?}`.", other);
}
};
}
#[test]
fn tag_str_error() {
const INPUT: &'static str = "Hello World!";
const TAG: &'static str = "Random";
match tag_s!(INPUT, TAG) {
IResult::Error(_) => (),
other => {
panic!("Parser `tag_s` didn't fail when it should have. Got `{:?}`.`", other);
},
};
}
use internal::IResult::{Done, Error};
use internal::Err::Position;
use util::ErrorKind;
pub fn is_alphabetic(c:char) -> bool {
(c as u8 >= 0x41 && c as u8 <= 0x5A) || (c as u8 >= 0x61 && c as u8 <= 0x7A)
}
#[test]
fn take_while_s() {
named!(f<&str,&str>, take_while_s!(is_alphabetic));
let a = "";
let b = "abcd";
let c = "abcd123";
let d = "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_s() {
named!(f<&str,&str>, take_while1_s!(is_alphabetic));
let a = "";
let b = "abcd";
let c = "abcd123";
let d = "123";
assert_eq!(f(&a[..]), Error(Position(ErrorKind::TakeWhile1Str, &""[..])));
assert_eq!(f(&b[..]), Done(&a[..], &b[..]));
assert_eq!(f(&c[..]), Done(&"123"[..], &b[..]));
assert_eq!(f(&d[..]), Error(Position(ErrorKind::TakeWhile1Str, &d[..])));
}
}