use std::borrow::Borrow;
use std::collections::HashMap;
use crate::response::ResponseCookiesIter;
use crate::{Processor, ResponseCookie, ResponseCookieId};
#[derive(Default, Debug, Clone)]
pub struct ResponseCookies<'cookie> {
cookies: HashMap<ResponseCookieKey<'cookie>, ResponseCookie<'cookie>>,
}
#[derive(Debug, Clone, Hash, Eq, PartialEq)]
pub(crate) struct ResponseCookieKey<'a>(ResponseCookieId<'a>);
impl<'a, 'b: 'a> Borrow<ResponseCookieId<'a>> for ResponseCookieKey<'b> {
fn borrow(&self) -> &ResponseCookieId<'a> {
&self.0
}
}
impl ResponseCookies<'static> {
pub fn new_static() -> ResponseCookies<'static> {
ResponseCookies::default()
}
}
impl<'cookie> ResponseCookies<'cookie> {
pub fn new() -> ResponseCookies<'cookie> {
ResponseCookies::default()
}
pub fn get<'map, 'key, Key>(&'map self, id: Key) -> Option<&'map ResponseCookie<'cookie>>
where
Key: Into<ResponseCookieId<'key>>,
{
let id = id.into();
self.cookies.get(&id)
}
pub fn insert<C: Into<ResponseCookie<'cookie>>>(
&mut self,
cookie: C,
) -> Option<ResponseCookie<'cookie>> {
let cookie = cookie.into();
self.cookies.insert(ResponseCookieKey(cookie.id()), cookie)
}
pub fn discard<'key, Key>(&mut self, id: Key)
where
Key: Into<ResponseCookieId<'key>>,
{
let id = id.into();
self.cookies.remove(&id);
}
pub fn iter<'map>(&'map self) -> ResponseCookiesIter<'map, 'cookie> {
ResponseCookiesIter {
cookies: self.cookies.values(),
}
}
}
impl<'a, 'c: 'a> ResponseCookies<'c> {
pub fn header_values(self, processor: &'a Processor) -> impl Iterator<Item = String> + 'a {
self.cookies
.into_values()
.map(|cookie| processor.process_outgoing(cookie).to_string())
}
}
#[cfg(test)]
mod test {
use super::ResponseCookies;
use crate::ResponseCookie;
#[test]
fn simple() {
let mut c = ResponseCookies::new();
c.insert(("test", ""));
c.insert(("test2", ""));
c.discard("test");
assert!(c.get("test").is_none());
assert!(c.get("test2").is_some());
c.insert(("test3", ""));
c.discard("test2");
c.discard("test3");
assert!(c.get("test").is_none());
assert!(c.get("test2").is_none());
assert!(c.get("test3").is_none());
}
#[test]
fn get_lifetime() {
fn get<'a>(
c: &'a ResponseCookies<'static>,
key: &str,
) -> Option<&'a ResponseCookie<'static>> {
c.get(key)
}
let mut c = ResponseCookies::new_static();
c.insert(("test", ""));
let key = "test".to_string();
c.get(key.as_str());
{
let key = "test".to_string();
get(&c, key.as_str());
}
}
#[test]
fn discard_lifetime() {
let mut c = ResponseCookies::new_static();
c.insert(("test", ""));
let key = "test".to_string();
c.discard(key.as_str());
}
#[test]
fn set_is_send() {
fn is_send<T: Send>(_: T) -> bool {
true
}
assert!(is_send(ResponseCookies::new()))
}
}