use std::collections::HashMap;
#[derive(Debug, Clone)]
pub struct CookieJar {
cookies: HashMap<String, String>,
}
impl CookieJar {
pub fn new() -> Self {
CookieJar {
cookies: HashMap::new(),
}
}
pub fn insert(&mut self, name: String, value: String) {
self.cookies.insert(name, value);
}
pub fn get(&self, name: &str) -> Option<&String> {
self.cookies.get(name)
}
pub fn remove(&mut self, name: &str) {
self.cookies.remove(name);
}
pub fn parse_from_headers(&mut self, headers: &HashMap<String, String>) {
for (key, value) in headers {
if key.eq_ignore_ascii_case("set-cookie") {
if let Some(cookie_pair) = value.split(';').next() {
if let Some((name, value)) = cookie_pair.split_once('=') {
self.cookies.insert(
name.trim().to_string(),
value.trim().to_string(),
);
}
}
}
}
}
pub fn build_cookie_header(&self) -> String {
self.cookies
.iter()
.map(|(name, value)| format!("{}={}", name, value))
.collect::<Vec<_>>()
.join("; ")
}
pub fn is_empty(&self) -> bool {
self.cookies.is_empty()
}
pub fn len(&self) -> usize {
self.cookies.len()
}
pub fn clear(&mut self) {
self.cookies.clear();
}
pub fn all(&self) -> &HashMap<String, String> {
&self.cookies
}
}
impl Default for CookieJar {
fn default() -> Self {
Self::new()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_cookie_jar_insert_and_get() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value".to_string());
assert_eq!(jar.get("name"), Some(&"value".to_string()));
}
#[test]
fn test_cookie_jar_remove() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value".to_string());
jar.remove("name");
assert_eq!(jar.get("name"), None);
}
#[test]
fn test_cookie_jar_build_header() {
let mut jar = CookieJar::new();
jar.insert("a".to_string(), "1".to_string());
jar.insert("b".to_string(), "2".to_string());
let header = jar.build_cookie_header();
assert!(header.contains("a=1"));
assert!(header.contains("b=2"));
}
#[test]
fn test_cookie_jar_parse_from_headers() {
let mut jar = CookieJar::new();
let mut headers = HashMap::new();
headers.insert("set-cookie".to_string(), "session=abc123; Path=/".to_string());
jar.parse_from_headers(&headers);
assert_eq!(jar.get("session"), Some(&"abc123".to_string()));
}
#[test]
fn test_cookie_jar_clear() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value".to_string());
jar.insert("another".to_string(), "test".to_string());
assert_eq!(jar.len(), 2);
jar.clear();
assert!(jar.is_empty());
assert_eq!(jar.len(), 0);
}
#[test]
fn test_cookie_jar_len() {
let mut jar = CookieJar::new();
assert_eq!(jar.len(), 0);
jar.insert("a".to_string(), "1".to_string());
assert_eq!(jar.len(), 1);
jar.insert("b".to_string(), "2".to_string());
assert_eq!(jar.len(), 2);
}
#[test]
fn test_cookie_jar_is_empty() {
let mut jar = CookieJar::new();
assert!(jar.is_empty());
jar.insert("name".to_string(), "value".to_string());
assert!(!jar.is_empty());
}
#[test]
fn test_cookie_jar_all() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value".to_string());
jar.insert("session".to_string(), "abc123".to_string());
let all_cookies = jar.all();
assert_eq!(all_cookies.len(), 2);
assert_eq!(all_cookies.get("name"), Some(&"value".to_string()));
assert_eq!(all_cookies.get("session"), Some(&"abc123".to_string()));
}
#[test]
fn test_cookie_jar_default() {
let jar = CookieJar::default();
assert!(jar.is_empty());
}
#[test]
fn test_cookie_jar_parse_multiple_set_cookie() {
let mut jar = CookieJar::new();
let mut headers = HashMap::new();
headers.insert("set-cookie".to_string(), "session=abc123; Path=/".to_string());
headers.insert("Set-Cookie".to_string(), "user=john; Domain=.example.com".to_string());
jar.parse_from_headers(&headers);
assert_eq!(jar.get("session"), Some(&"abc123".to_string()));
assert_eq!(jar.get("user"), Some(&"john".to_string()));
}
#[test]
fn test_cookie_jar_parse_case_insensitive() {
let mut jar = CookieJar::new();
let mut headers = HashMap::new();
headers.insert("SET-COOKIE".to_string(), "test=value".to_string());
jar.parse_from_headers(&headers);
assert_eq!(jar.get("test"), Some(&"value".to_string()));
}
#[test]
fn test_cookie_jar_parse_no_set_cookie() {
let mut jar = CookieJar::new();
let mut headers = HashMap::new();
headers.insert("content-type".to_string(), "text/html".to_string());
jar.parse_from_headers(&headers);
assert!(jar.is_empty());
}
#[test]
fn test_cookie_jar_parse_empty_value() {
let mut jar = CookieJar::new();
let mut headers = HashMap::new();
headers.insert("set-cookie".to_string(), "test=".to_string());
jar.parse_from_headers(&headers);
assert_eq!(jar.get("test"), Some(&"".to_string()));
}
#[test]
fn test_cookie_jar_parse_with_attributes() {
let mut jar = CookieJar::new();
let mut headers = HashMap::new();
headers.insert("set-cookie".to_string(), "session=abc123; Path=/; Domain=.example.com; Secure; HttpOnly".to_string());
jar.parse_from_headers(&headers);
assert_eq!(jar.get("session"), Some(&"abc123".to_string()));
}
#[test]
fn test_cookie_jar_insert_replace() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value1".to_string());
assert_eq!(jar.get("name"), Some(&"value1".to_string()));
jar.insert("name".to_string(), "value2".to_string());
assert_eq!(jar.get("name"), Some(&"value2".to_string()));
}
#[test]
fn test_cookie_jar_build_empty() {
let jar = CookieJar::new();
let header = jar.build_cookie_header();
assert_eq!(header, "");
}
#[test]
fn test_cookie_jar_build_single() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value".to_string());
let header = jar.build_cookie_header();
assert_eq!(header, "name=value");
}
#[test]
fn test_cookie_jar_build_multiple() {
let mut jar = CookieJar::new();
jar.insert("a".to_string(), "1".to_string());
jar.insert("b".to_string(), "2".to_string());
jar.insert("c".to_string(), "3".to_string());
let header = jar.build_cookie_header();
assert!(header.contains("a=1"));
assert!(header.contains("b=2"));
assert!(header.contains("c=3"));
assert!(header.contains("; "));
}
#[test]
fn test_cookie_jar_get_nonexistent() {
let jar = CookieJar::new();
assert_eq!(jar.get("nonexistent"), None);
}
#[test]
fn test_cookie_jar_remove_nonexistent() {
let mut jar = CookieJar::new();
jar.insert("name".to_string(), "value".to_string());
jar.remove("nonexistent");
assert_eq!(jar.len(), 1);
assert_eq!(jar.get("name"), Some(&"value".to_string()));
}
}