pub use tower_http::cors::*;
#[derive(Debug)]
#[derive(serde::Deserialize)]
pub struct Settings {
pub preset: Option<SettingsPreset>,
pub allow_credentials: Option<bool>,
pub allow_headers: Option<SettingsAllowHeaders>,
pub allow_methods: Option<SettingsAllowMethods>,
pub allow_origin: Option<SettingsAllowOrigin>,
pub allow_private_network: Option<bool>,
pub expose_headers: Option<SettingsExposeHeaders>,
pub max_age: Option<SettingsMaxAge>,
pub vary: Option<SettingsVary>,
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum SettingsPreset {
Default,
Permissive,
VeryPermissive,
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum SettingsAllowHeaders {
#[serde(deserialize_with = "is_wildcard")]
Any(char),
List(Vec<String>),
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum SettingsAllowMethods {
#[serde(deserialize_with = "is_wildcard")]
Any(char),
Exact(crate::routing::Method),
List(Vec<crate::routing::Method>),
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum SettingsAllowOrigin {
#[serde(deserialize_with = "is_wildcard")]
Any(char),
Exact(String),
List(Vec<String>),
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum SettingsExposeHeaders {
#[serde(deserialize_with = "is_wildcard")]
Any(char),
List(Vec<String>),
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum SettingsMaxAge {
Exact(u64),
}
#[derive(Debug)]
#[derive(serde::Deserialize)]
#[serde(untagged)]
pub enum SettingsVary {
List(Vec<String>),
}
impl From<&SettingsAllowHeaders> for AllowHeaders {
fn from(this: &SettingsAllowHeaders) -> Self {
match this {
| SettingsAllowHeaders::Any(_) => Self::any(),
| SettingsAllowHeaders::List(list) => {
Self::list(list.iter().flat_map(|hr| hr.parse()))
}
}
}
}
impl From<&SettingsAllowMethods> for AllowMethods {
fn from(this: &SettingsAllowMethods) -> Self {
match this {
| SettingsAllowMethods::Any(_) => Self::any(),
| SettingsAllowMethods::Exact(method) => {
Self::exact(match method {
| crate::routing::Method::DELETE => {
axum::http::Method::DELETE
}
| crate::routing::Method::GET => axum::http::Method::GET,
| crate::routing::Method::HEAD => axum::http::Method::HEAD,
| crate::routing::Method::OPTIONS => {
axum::http::Method::OPTIONS
}
| crate::routing::Method::PATCH => {
axum::http::Method::PATCH
}
| crate::routing::Method::POST => axum::http::Method::POST,
| crate::routing::Method::PUT => axum::http::Method::PUT,
| crate::routing::Method::TRACE => {
axum::http::Method::TRACE
}
})
}
| SettingsAllowMethods::List(list) => {
Self::list(list.iter().map(|method| {
match method {
| crate::routing::Method::DELETE => {
axum::http::Method::DELETE
}
| crate::routing::Method::GET => {
axum::http::Method::GET
}
| crate::routing::Method::HEAD => {
axum::http::Method::HEAD
}
| crate::routing::Method::OPTIONS => {
axum::http::Method::OPTIONS
}
| crate::routing::Method::PATCH => {
axum::http::Method::PATCH
}
| crate::routing::Method::POST => {
axum::http::Method::POST
}
| crate::routing::Method::PUT => {
axum::http::Method::PUT
}
| crate::routing::Method::TRACE => {
axum::http::Method::TRACE
}
}
}))
}
}
}
}
impl From<&SettingsAllowOrigin> for AllowOrigin {
fn from(this: &SettingsAllowOrigin) -> Self {
match this {
| SettingsAllowOrigin::Any(_) => Self::any(),
| SettingsAllowOrigin::Exact(value) => {
if let Ok(value) = value.parse() {
return Self::exact(value);
}
Self::default()
}
| SettingsAllowOrigin::List(list) => {
Self::list(list.iter().flat_map(|value| value.parse()))
}
}
}
}
impl From<&SettingsExposeHeaders> for ExposeHeaders {
fn from(this: &SettingsExposeHeaders) -> Self {
match this {
| SettingsExposeHeaders::Any(_) => Self::any(),
| SettingsExposeHeaders::List(list) => {
Self::list(list.iter().flat_map(|value| value.parse()))
}
}
}
}
impl From<&SettingsMaxAge> for MaxAge {
fn from(this: &SettingsMaxAge) -> Self {
match this {
| SettingsMaxAge::Exact(secs) => {
Self::exact(std::time::Duration::from_secs(*secs))
}
}
}
}
impl From<&SettingsVary> for Vary {
fn from(this: &SettingsVary) -> Self {
match this {
| SettingsVary::List(list) => {
Self::list(list.iter().flat_map(|value| value.parse()))
}
}
}
}
fn is_wildcard<'de, D>(deserializer: D) -> Result<char, D::Error>
where
D: serde::Deserializer<'de>,
{
let value = <_ as serde::Deserialize>::deserialize(deserializer)?;
if value != '*' {
return Err(serde::de::Error::custom(
"Seul le caractère '*' est autorisé.",
));
}
Ok(value)
}