use std::time::Duration;
use anyhow::{Ok, Result};
use cookie::{
Cookie as CookieJar,
time::{Duration as CookieDuration, OffsetDateTime},
SameSite as CookieSomeSite
};
use crate::utils::Values;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum SameSite {
Strict,
Lax,
None
}
#[derive(Debug)]
pub struct Cookie {
name: String,
value: String,
expires: Option<Duration>,
max_age: Option<Duration>,
domain: Option<String>,
path: Option<String>,
secure: Option<bool>,
http_only: Option<bool>,
same_site: Option<SameSite>
}
#[derive(Debug)]
pub struct Cookies {
pub(crate) cookies: Values,
pub(crate) new_cookie: Vec<Cookie>,
}
impl Cookie {
pub fn new(name: &str, value: &str) -> Self {
return Self {
name: name.to_string(),
value: value.to_string(),
expires: None,
max_age: None,
domain: None,
path: None,
secure: None,
http_only: None,
same_site: None
}
}
pub fn set_name(&mut self, value: &str) -> &mut Self {
self.name = value.to_string();
return self;
}
pub fn set_value(&mut self, value: &str) -> &mut Self {
self.value = value.to_string();
return self;
}
pub fn set_expires(&mut self, duration: Duration) -> &mut Self {
self.expires = Some(duration);
return self;
}
pub fn set_max_age(&mut self, duration: Duration) -> &mut Self {
self.max_age = Some(duration);
return self;
}
pub fn set_path(&mut self, value: &str) -> &mut Self {
self.path = Some(value.to_string());
return self;
}
pub fn set_domain(&mut self, value: &str) -> &mut Self {
self.domain = Some(value.to_string());
return self;
}
pub fn set_secure(&mut self, value: bool) -> &mut Self {
self.secure = Some(value);
return self;
}
pub fn set_http_only(&mut self, value: bool) -> &mut Self {
self.http_only = Some(value);
return self;
}
pub fn set_same_site(&mut self, value: SameSite) -> &mut Self {
self.same_site = Some(value);
return self;
}
pub(crate) fn parse(&mut self) -> String {
let mut cookie = CookieJar::new(self.name.to_string(), self.value.to_string());
if let Some(expires) = self.expires {
cookie.set_expires(OffsetDateTime::now_utc() + CookieDuration::seconds(expires.as_secs() as i64));
}
if let Some(max_age) = self.max_age {
cookie.set_max_age(CookieDuration::new(max_age.as_secs() as i64, 0));
}
if let Some(path) = &self.path {
cookie.set_path(path);
}
if let Some(domain) = &self.domain {
cookie.set_domain(domain);
}
if let Some(secure) = self.secure {
cookie.set_secure(secure);
}
if let Some(http_only) = self.http_only {
cookie.set_http_only(http_only);
}
if let Some(same_site) = self.same_site {
match same_site {
SameSite::Strict => cookie.set_same_site(CookieSomeSite::Strict),
SameSite::Lax => cookie.set_same_site(CookieSomeSite::Lax),
SameSite::None => cookie.set_same_site(CookieSomeSite::None),
}
}
return cookie.to_string();
}
}
impl Cookies {
pub fn new(cookies: Values) -> Self {
return Self {
cookies: cookies,
new_cookie: vec![],
}
}
pub fn get(&mut self, name: &str) -> String {
return self.cookies.get(name).map(|v| String::from(v)).unwrap_or(String::new());
}
pub fn set(&mut self, name: &str, value: &str) -> &mut Cookie {
let idx = self.new_cookie.len();
self.new_cookie.push(Cookie::new(name, value));
return &mut self.new_cookie[idx];
}
pub fn remove(&mut self, name: &str) -> Result<()> {
self.cookies.remove(name);
return Ok(())
}
}