use std::borrow::Cow;
use std::sync::Arc;
const UNNAMEABLE_METHOD: &str = "UNKNOWN";
#[derive(Clone, Debug)]
pub(super) enum RequestMethod {
Known(Method),
Unnameable(Arc<str>),
}
impl RequestMethod {
pub(super) fn from_hyper(method: &hyper::Method) -> Self {
Method::from_hyper(method)
.map_or_else(|| Self::Unnameable(Arc::from(method.as_str())), Self::Known)
}
pub(super) fn routable(&self) -> Option<Method> {
match self {
Self::Known(method) => Some(*method),
Self::Unnameable(_) => None,
}
}
pub(super) fn as_str(&self) -> &str {
match self {
Self::Known(method) => method.as_str(),
Self::Unnameable(text) => text,
}
}
pub(super) fn to_cow(&self) -> Cow<'static, str> {
match self {
Self::Known(method) => Cow::Borrowed(method.as_str()),
Self::Unnameable(text) => Cow::Owned(text.to_string()),
}
}
pub(super) fn label(&self) -> &'static str {
match self {
Self::Known(method) => method.as_str(),
Self::Unnameable(_) => UNNAMEABLE_METHOD,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub enum Method {
Get,
Post,
Put,
Delete,
Patch,
Head,
Options,
}
impl std::fmt::Display for Method {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ParseMethodError;
impl std::fmt::Display for ParseMethodError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str("unknown HTTP method")
}
}
impl std::error::Error for ParseMethodError {}
impl std::str::FromStr for Method {
type Err = ParseMethodError;
fn from_str(s: &str) -> Result<Self, Self::Err> {
Self::parse(s).ok_or(ParseMethodError)
}
}
impl Method {
pub(super) const COUNT: usize = 7;
pub(super) fn parse(s: &str) -> Option<Self> {
match s {
"GET" => Some(Self::Get),
"POST" => Some(Self::Post),
"PUT" => Some(Self::Put),
"DELETE" => Some(Self::Delete),
"PATCH" => Some(Self::Patch),
"HEAD" => Some(Self::Head),
"OPTIONS" => Some(Self::Options),
_ => None,
}
}
pub(super) fn from_hyper(m: &hyper::Method) -> Option<Self> {
Self::parse(m.as_str())
}
pub(super) fn from_reqwest(m: &reqwest::Method) -> Option<Self> {
Self::parse(m.as_str())
}
pub fn as_str(self) -> &'static str {
match self {
Self::Get => "GET",
Self::Post => "POST",
Self::Put => "PUT",
Self::Delete => "DELETE",
Self::Patch => "PATCH",
Self::Head => "HEAD",
Self::Options => "OPTIONS",
}
}
pub(super) const fn ordinal(self) -> usize {
match self {
Self::Get => 0,
Self::Post => 1,
Self::Put => 2,
Self::Delete => 3,
Self::Patch => 4,
Self::Head => 5,
Self::Options => 6,
}
}
}
const _: () = assert!(Method::Options.ordinal() + 1 == Method::COUNT);