use axol_http::{
Method, header::TypedHeader, request::RequestPartsRef, typed_headers::AccessControlAllowMethods,
};
use super::Any;
#[derive(Clone, Debug)]
#[must_use]
pub enum AllowMethods {
Const(Option<String>),
MirrorRequest,
}
impl Default for AllowMethods {
fn default() -> Self {
Self::Const(None)
}
}
impl AllowMethods {
pub fn any() -> Self {
Self::Const(Some("*".to_string()))
}
pub fn exact(method: Method) -> Self {
Self::Const(Some(method.to_string()))
}
pub fn list<I: IntoIterator<Item = Method>>(methods: I) -> Self {
let raw = methods
.into_iter()
.map(|x| x.as_str())
.collect::<Vec<_>>()
.join(",");
if raw.is_empty() {
return Self::Const(None);
}
Self::Const(Some(raw))
}
pub fn mirror_request() -> Self {
Self::MirrorRequest
}
pub(super) fn is_wildcard(&self) -> bool {
matches!(self, AllowMethods::Const(Some(x)) if x == "*")
}
pub(super) fn to_header(
&self,
parts: RequestPartsRef<'_>,
) -> Option<AccessControlAllowMethods> {
match self {
Self::Const(Some(v)) => Some(AccessControlAllowMethods::decode(v).unwrap()),
Self::Const(None) => None,
Self::MirrorRequest => parts
.headers
.get_typed::<AccessControlAllowMethods>()
.clone(),
}
}
}
impl From<Any> for AllowMethods {
fn from(_: Any) -> Self {
Self::any()
}
}
impl From<Method> for AllowMethods {
fn from(method: Method) -> Self {
Self::exact(method)
}
}
impl<const N: usize> From<[Method; N]> for AllowMethods {
fn from(arr: [Method; N]) -> Self {
Self::list(arr)
}
}
impl From<Vec<Method>> for AllowMethods {
fn from(vec: Vec<Method>) -> Self {
Self::list(vec)
}
}