orgize/src/elements/cookie.rs
2019-06-27 02:57:23 +08:00

66 lines
1.8 KiB
Rust

use memchr::{memchr, memchr2};
#[cfg_attr(test, derive(PartialEq))]
#[derive(Debug)]
pub enum Cookie<'a> {
Percent(&'a str),
Slash(&'a str, &'a str),
}
impl Cookie<'_> {
#[inline]
// return (clock, offset)
pub(crate) fn parse(src: &str) -> Option<(Cookie<'_>, usize)> {
debug_assert!(src.starts_with('['));
let bytes = src.as_bytes();
let num1 =
memchr2(b'%', b'/', bytes).filter(|&i| bytes[1..i].iter().all(u8::is_ascii_digit))?;
if bytes[num1] == b'%' && *bytes.get(num1 + 1)? == b']' {
Some((Cookie::Percent(&src[1..num1]), num1 + 2))
} else {
let num2 = memchr(b']', bytes)
.filter(|&i| bytes[num1 + 1..i].iter().all(u8::is_ascii_digit))?;
Some((Cookie::Slash(&src[1..num1], &src[num1 + 1..num2]), num2 + 1))
}
}
}
#[test]
fn parse() {
assert_eq!(
Cookie::parse("[1/10]"),
Some((Cookie::Slash("1", "10"), "[1/10]".len()))
);
assert_eq!(
Cookie::parse("[1/1000]"),
Some((Cookie::Slash("1", "1000"), "[1/1000]".len()))
);
assert_eq!(
Cookie::parse("[10%]"),
Some((Cookie::Percent("10"), "[10%]".len()))
);
assert_eq!(
Cookie::parse("[%]"),
Some((Cookie::Percent(""), "[%]".len()))
);
assert_eq!(
Cookie::parse("[/]"),
Some((Cookie::Slash("", ""), "[/]".len()))
);
assert_eq!(
Cookie::parse("[100/]"),
Some((Cookie::Slash("100", ""), "[100/]".len()))
);
assert_eq!(
Cookie::parse("[/100]"),
Some((Cookie::Slash("", "100"), "[/100]".len()))
);
assert_eq!(Cookie::parse("[10% ]"), None);
assert_eq!(Cookie::parse("[1//100]"), None);
assert_eq!(Cookie::parse("[1\\100]"), None);
assert_eq!(Cookie::parse("[10%%]"), None);
}