Skip to content

Instantly share code, notes, and snippets.

@paul-english
Last active May 11, 2016 20:18
Show Gist options
  • Save paul-english/d9c3fc9598cf2d92b8ae89a9ce5341d8 to your computer and use it in GitHub Desktop.
Save paul-english/d9c3fc9598cf2d92b8ae89a9ce5341d8 to your computer and use it in GitHub Desktop.
macro_rules! caseless_tag (
($i:expr, $inp: expr) => (
{
#[inline(always)]
fn as_lower(b: &str) -> String {
let s = b.to_string();
s.to_lowercase()
}
let expected = $inp;
let lower = as_lower(&expected);
let bytes = lower.as_bytes();
caseless_tag_bytes!($i,bytes)
}
);
);
macro_rules! caseless_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 s = from_utf8(reduced).unwrap();
let s2 = s.to_string();
let lowered = s2.to_lowercase();
let lowered_bytes = lowered.as_bytes();
let b = &$bytes[..m];
let res: IResult<_,_> = if lowered_bytes != b {
IResult::Error(Err::Position(ErrorKind::Tag, $i))
} else if m < blen {
IResult::Incomplete(Needed::Size(blen))
} else {
IResult::Done(&$i[blen..], reduced)
};
res
}
);
);
#[test]
fn test_caseless_tag() {
named!(x, caseless_tag!("AbCD"));
let r = x(&b"abcdefGH"[..]);
assert_eq!(r, Done(&b"efGH"[..], &b"abcd"[..]));
let r = x(&b"aBcdefGH"[..]);
assert_eq!(r, Done(&b"efGH"[..], &b"aBcd"[..]));
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment