use std::convert::Infallible;
use cookie::Cookie;
use cookie::CookieJar as RawJar;
use http::HeaderMap;
use http::header::COOKIE;
use http::request::Parts;
use crate::extractors::FromRequest;
use crate::extractors::FromRequestParts;
use crate::types::Request;
pub struct CookieJar(RawJar);
impl CookieJar {
pub fn new() -> Self {
Self(RawJar::new())
}
pub fn from_headers(headers: &HeaderMap) -> Self {
let mut jar = RawJar::new();
if let Some(val) = headers.get(COOKIE).and_then(|v| v.to_str().ok()) {
for s in val.split(';') {
if let Ok(c) = Cookie::parse(s.trim()) {
jar.add_original(c.into_owned());
}
}
}
Self(jar)
}
pub fn add(&mut self, cookie: Cookie<'static>) {
self.0.add(cookie);
}
pub fn remove(&mut self, name: &str) {
self.0.remove(Cookie::from(name.to_owned()));
}
pub fn get(&self, name: &str) -> Option<&Cookie<'_>> {
self.0.get(name)
}
pub fn iter(&self) -> impl Iterator<Item = &Cookie<'static>> {
self.0.iter()
}
}
impl<'a> FromRequest<'a> for CookieJar {
type Error = Infallible;
fn from_request(
req: &'a mut Request,
) -> impl core::future::Future<Output = core::result::Result<Self, Self::Error>> + Send + 'a {
futures_util::future::ready(Ok(CookieJar::from_headers(req.headers())))
}
}
impl<'a> FromRequestParts<'a> for CookieJar {
type Error = Infallible;
fn from_request_parts(
parts: &'a mut Parts,
) -> impl core::future::Future<Output = core::result::Result<Self, Self::Error>> + Send + 'a {
futures_util::future::ready(Ok(CookieJar::from_headers(&parts.headers)))
}
}