pub struct Cookies<'a> {
cookies: &'a [u8],
}
impl<'a> Cookies<'a> {
pub fn new(cookies: Option<&'a [u8]>) -> Self {
Cookies {
cookies: cookies.unwrap_or(b""),
}
}
pub fn find(&self, cookie: &str) -> Option<&'a [u8]> {
for mut c in self.cookies.split(|&v| v == b';') {
while let Some((b' ', rest)) = c.split_first() {
c = rest;
}
let mut split = c.splitn(2, |&v| v == b'=');
let name = split.next()?;
let mut value = match split.next() {
Some(v) => v,
None => continue,
};
if name == cookie.as_bytes() {
if value.len() >= 2 && value.first() == Some(&b'"') && value.last() == Some(&b'"') {
value = &value[1..value.len() - 1];
}
return Some(value);
}
}
None
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_find_cookie() {
let cookies = Cookies::new(Some(b"foo=bar; baz=qux; test=\"quotes\"; qux"));
assert_eq!(cookies.find("foo"), Some(b"bar" as &[u8]));
assert_eq!(cookies.find("baz"), Some(b"qux" as &[u8]));
assert_eq!(cookies.find("test"), Some(b"quotes" as &[u8]));
assert_eq!(cookies.find("qux"), None);
let cookies = Cookies::new(Some(b"foo=bar; baz=qux"));
assert_eq!(cookies.find("baz"), Some(b"qux" as &[u8]));
let cookies = Cookies::new(Some(b"foo=\"bar"));
assert_eq!(cookies.find("foo"), Some(b"\"bar" as &[u8]));
let cookies = Cookies::new(Some(b"foo=bar\""));
assert_eq!(cookies.find("foo"), Some(b"bar\"" as &[u8]));
let cookies = Cookies::new(Some(b"foo=\"\""));
assert_eq!(cookies.find("foo"), Some(b"" as &[u8]));
let cookies = Cookies::new(Some(b"foo; baz=qux"));
assert_eq!(cookies.find("foo"), None);
assert_eq!(cookies.find("baz"), Some(b"qux" as &[u8]));
}
}