use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, Serialize, Deserialize, PartialEq, Eq)]
pub enum SameSite {
Strict,
Lax,
None,
Default,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Cookie {
pub name: String,
pub value: String,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub path: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub domain: Option<String>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub secure: Option<bool>,
#[serde(rename = "httpOnly", skip_serializing_if = "Option::is_none", default)]
pub http_only: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none", default)]
pub expiry: Option<i64>,
#[serde(skip_serializing_if = "Option::is_none", rename = "sameSite", default)]
pub same_site: Option<SameSite>,
}
impl Cookie {
pub fn new(name: impl Into<String>, value: impl Into<String>) -> Self {
Cookie {
name: name.into(),
value: value.into(),
path: None,
domain: None,
secure: None,
http_only: None,
expiry: None,
same_site: None,
}
}
pub fn set_path(&mut self, path: impl Into<String>) {
self.path = Some(path.into());
}
pub fn set_domain(&mut self, domain: impl Into<String>) {
self.domain = Some(domain.into());
}
pub fn set_secure(&mut self, secure: bool) {
self.secure = Some(secure);
}
pub fn set_http_only(&mut self, http_only: bool) {
self.http_only = Some(http_only);
}
pub fn set_expiry(&mut self, expiry: i64) {
self.expiry = Some(expiry);
}
pub fn set_same_site(&mut self, same_site: SameSite) {
self.same_site = Some(same_site);
}
}
#[cfg(feature = "bidi")]
pub(crate) mod bidi {
pub(crate) fn bytes_string(value: impl Into<String>) -> serde_json::Value {
serde_json::json!({"type": "string", "value": value.into()})
}
pub(crate) fn string_from_bytes_value(v: &serde_json::Value) -> String {
v.get("value").and_then(|s| s.as_str()).unwrap_or_default().to_string()
}
pub(crate) mod same_site {
use super::super::SameSite;
use serde::{Deserialize, Deserializer, Serialize, Serializer};
pub(crate) fn serialize<S>(value: &SameSite, ser: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let s = match value {
SameSite::Strict => "strict",
SameSite::Lax => "lax",
SameSite::None => "none",
SameSite::Default => "default",
};
s.serialize(ser)
}
pub(crate) fn deserialize<'de, D>(de: D) -> Result<SameSite, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(de)?;
match s.as_str() {
"strict" => Ok(SameSite::Strict),
"lax" => Ok(SameSite::Lax),
"none" => Ok(SameSite::None),
"default" => Ok(SameSite::Default),
other => Err(serde::de::Error::unknown_variant(
other,
&["strict", "lax", "none", "default"],
)),
}
}
#[allow(dead_code)] pub(crate) mod option {
use super::SameSite;
use serde::{Deserialize, Deserializer, Serializer};
pub(crate) fn serialize<S>(value: &Option<SameSite>, ser: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
match value {
Some(v) => super::serialize(v, ser),
None => ser.serialize_none(),
}
}
pub(crate) fn deserialize<'de, D>(de: D) -> Result<Option<SameSite>, D::Error>
where
D: Deserializer<'de>,
{
let opt = Option::<String>::deserialize(de)?;
opt.map(|s| match s.as_str() {
"strict" => Ok(SameSite::Strict),
"lax" => Ok(SameSite::Lax),
"none" => Ok(SameSite::None),
"default" => Ok(SameSite::Default),
other => Err(serde::de::Error::unknown_variant(
other,
&["strict", "lax", "none", "default"],
)),
})
.transpose()
}
}
}
}