use std::time::Duration;
#[derive(Clone, Debug, Default)]
pub enum SameSite {
Strict,
#[default]
Lax,
None,
}
impl SameSite {
pub fn as_str(&self) -> &'static str {
match self {
SameSite::Strict => "Strict",
SameSite::Lax => "Lax",
SameSite::None => "None",
}
}
}
#[derive(Clone, Debug)]
pub struct CookieOptions {
pub max_age: Option<Duration>,
pub http_only: bool,
pub secure: bool,
pub same_site: SameSite,
pub path: String,
}
impl Default for CookieOptions {
fn default() -> Self {
Self {
max_age: None,
http_only: true,
secure: true,
same_site: SameSite::Lax,
path: "/".to_string(),
}
}
}
impl CookieOptions {
pub fn build_header(&self, name: &str, value: &str) -> String {
let mut s = format!("{}={}", name, urlencoding::encode(value));
if self.http_only {
s.push_str("; HttpOnly");
}
if self.secure {
s.push_str("; Secure");
}
s.push_str("; SameSite=");
s.push_str(self.same_site.as_str());
s.push_str("; Path=");
s.push_str(&self.path);
if let Some(max_age) = self.max_age {
s.push_str("; Max-Age=");
s.push_str(&max_age.as_secs().to_string());
}
s
}
}
#[derive(Debug, Clone, thiserror::Error)]
#[error("CookieError: {message}")]
pub struct CookieError {
pub message: String,
}
impl CookieError {
pub fn new(message: impl Into<String>) -> Self {
Self {
message: message.into(),
}
}
}
#[cfg(feature = "server")]
impl From<CookieError> for dioxus::prelude::ServerFnError {
fn from(err: CookieError) -> Self {
dioxus::prelude::ServerFnError::new(err.message)
}
}