use crate::*;
impl CookieBuilder {
#[inline(always)]
pub fn new<N, V>(name: N, value: V) -> Self
where
N: AsRef<str>,
V: AsRef<str>,
{
Self {
name: name.as_ref().to_owned(),
value: value.as_ref().to_owned(),
expires: None,
max_age: None,
domain: None,
path: None,
secure: None,
http_only: None,
same_site: None,
}
}
pub fn parse<C>(cookie: C) -> Self
where
C: AsRef<str>,
{
let mut cookie_builder: Self = Self::default();
let parts: Vec<&str> = cookie.as_ref().split(SEMICOLON).collect();
if parts.is_empty() {
return cookie_builder;
}
if let Some(name_value_pair) = parts.first() {
let name_value_pair: &str = name_value_pair.trim();
if let Some((name, value)) = name_value_pair.split_once(EQUAL) {
cookie_builder.name = name.trim().to_string();
cookie_builder.value = value.trim().to_string();
} else if !name_value_pair.is_empty() {
cookie_builder.name = name_value_pair.to_string();
cookie_builder.value = String::new();
}
}
for part in parts.iter().skip(1) {
let part: &str = part.trim();
if part.is_empty() {
continue;
}
if let Some((key, value)) = part.split_once(EQUAL) {
let key_lowercase: String = key.trim().to_lowercase();
let value: String = value.trim().to_string();
match key_lowercase.as_str() {
COOKIE_EXPIRES_LOWERCASE => {
cookie_builder.set_expires(value);
}
COOKIE_MAX_AGE_LOWERCASE => {
if let Ok(max_age_value) = value.parse::<i64>() {
cookie_builder.set_max_age(max_age_value);
}
}
COOKIE_DOMAIN_LOWERCASE => {
cookie_builder.set_domain(value);
}
COOKIE_PATH_LOWERCASE => {
cookie_builder.set_path(value);
}
COOKIE_SAME_SITE_LOWERCASE => {
cookie_builder.set_same_site(value);
}
_ => {}
}
} else {
let attribute_lowercase: String = part.to_lowercase();
match attribute_lowercase.as_str() {
COOKIE_SECURE_LOWERCASE => {
cookie_builder.secure = Some(true);
}
COOKIE_HTTP_ONLY_LOWERCASE => {
cookie_builder.http_only = Some(true);
}
_ => {}
}
}
}
cookie_builder
}
#[inline(always)]
pub fn set_expires<E>(&mut self, expires: E) -> &mut Self
where
E: AsRef<str>,
{
self.expires = Some(expires.as_ref().to_owned());
self
}
#[inline(always)]
pub fn set_max_age<M>(&mut self, max_age: M) -> &mut Self
where
M: Into<i64>,
{
self.max_age = Some(max_age.into());
self
}
#[inline(always)]
pub fn set_domain<D>(&mut self, domain: D) -> &mut Self
where
D: AsRef<str>,
{
self.domain = Some(domain.as_ref().to_owned());
self
}
#[inline(always)]
pub fn set_path<T>(&mut self, path: T) -> &mut Self
where
T: AsRef<str>,
{
self.path = Some(path.as_ref().to_owned());
self
}
#[inline(always)]
pub fn secure(&mut self) -> &mut Self {
self.secure = Some(true);
self
}
#[inline(always)]
pub fn http_only(&mut self) -> &mut Self {
self.http_only = Some(true);
self
}
#[inline(always)]
pub fn disable_secure(&mut self) -> &mut Self {
self.secure = Some(false);
self
}
#[inline(always)]
pub fn disable_http_only(&mut self) -> &mut Self {
self.http_only = Some(false);
self
}
#[inline(always)]
pub fn set_same_site<T>(&mut self, same_site: T) -> &mut Self
where
T: AsRef<str>,
{
self.same_site = Some(same_site.as_ref().to_owned());
self
}
pub fn build(&self) -> String {
if self.get_name().is_empty() {
return String::new();
}
let mut cookie_string: String = format!("{}={}", self.get_name(), self.get_value());
if let Some(expires_value) = self.try_get_expires() {
cookie_string.push_str(COOKIE_EXPIRES_ATTRIBUTE_LOWERCASE);
cookie_string.push_str(expires_value);
}
if let Some(max_age_value) = self.try_get_max_age() {
cookie_string.push_str(COOKIE_MAX_AGE_ATTRIBUTE_LOWERCASE);
cookie_string.push_str(&max_age_value.to_string());
}
if let Some(domain_value) = self.try_get_domain() {
cookie_string.push_str(COOKIE_DOMAIN_ATTRIBUTE_LOWERCASE);
cookie_string.push_str(domain_value);
}
if let Some(path_value) = self.try_get_path() {
cookie_string.push_str(COOKIE_PATH_ATTRIBUTE_LOWERCASE);
cookie_string.push_str(path_value);
}
if let Some(true) = self.try_get_secure() {
cookie_string.push_str(COOKIE_SECURE_ATTRIBUTE_LOWERCASE);
}
if let Some(true) = self.try_get_http_only() {
cookie_string.push_str(COOKIE_HTTP_ONLY_ATTRIBUTE_LOWERCASE);
}
if let Some(same_site_value) = self.try_get_same_site() {
cookie_string.push_str(COOKIE_SAME_SITE_ATTRIBUTE_LOWERCASE);
cookie_string.push_str(same_site_value);
}
cookie_string
}
}
impl Cookie {
pub fn parse<C>(cookie: C) -> Cookies
where
C: AsRef<str>,
{
let cookie_ref: &str = cookie.as_ref();
let mut cookies: Cookies = hash_map_xx_hash3_64();
if cookie_ref.trim().is_empty() {
return cookies;
}
let parts: Vec<&str> = cookie_ref.split(SEMICOLON).collect();
for part in parts {
let part: &str = part.trim();
if part.is_empty() {
continue;
}
if let Some((name, value)) = part.split_once(EQUAL) {
let name: String = name.trim().to_string();
let value: String = value.trim().to_string();
if !name.is_empty() {
cookies.insert(name, value);
}
} else if !part.is_empty() {
cookies.insert(part.to_string(), String::new());
}
}
cookies
}
}