use std::{fmt::Display, net::SocketAddr};
#[cfg_attr(feature = "json", derive(serde::Serialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum Method {
GET,
POST,
PUT,
DELETE,
HEAD,
OPTIONS,
CONNECT,
PATCH,
TRACE,
UNKNOWN,
}
impl Display for Method {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
let method = match self {
Method::GET => "GET",
Method::POST => "POST",
Method::PUT => "PUT",
Method::DELETE => "DELETE",
Method::HEAD => "HEAD",
Method::OPTIONS => "OPTIONS",
Method::CONNECT => "CONNECT",
Method::PATCH => "PATCH",
Method::TRACE => "TRACE",
Method::UNKNOWN => "UNKNOWN",
};
write!(f, "{}", method)
}
}
impl From<&str> for Method {
fn from(method: &str) -> Self {
match method {
"GET" => Method::GET,
"POST" => Method::POST,
"PUT" => Method::PUT,
"DELETE" => Method::DELETE,
"HEAD" => Method::HEAD,
"OPTIONS" => Method::OPTIONS,
"CONNECT" => Method::CONNECT,
"PATCH" => Method::PATCH,
"TRACE" => Method::TRACE,
_ => Method::UNKNOWN,
}
}
}
#[cfg_attr(feature = "json", derive(serde::Serialize))]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum HttpVersion {
V1_0,
V1_1,
V2_0,
V3_0,
UNKNOWN,
}
impl Display for HttpVersion {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"HTTP/{}",
match self {
HttpVersion::V1_0 => "1.0",
HttpVersion::V1_1 => "1.1",
HttpVersion::V2_0 => "2.0",
HttpVersion::V3_0 => "3.0",
HttpVersion::UNKNOWN => "1.1",
}
)
}
}
impl From<&str> for HttpVersion {
fn from(version: &str) -> Self {
match version {
"HTTP/1.0" => HttpVersion::V1_0,
"HTTP/1.1" => HttpVersion::V1_1,
"HTTP/2.0" => HttpVersion::V2_0,
"HTTP/3.0" => HttpVersion::V3_0,
_ => HttpVersion::UNKNOWN,
}
}
}
pub fn format_addr(addr: SocketAddr) -> String {
match addr {
SocketAddr::V4(v4) => {
if v4.ip().is_loopback() {
format!("localhost:{}", v4.port())
} else {
v4.to_string()
}
}
SocketAddr::V6(v6) => {
if v6.ip().is_loopback() {
format!("localhost:{}", v6.port())
} else {
format!("{}:{}", v6.ip(), v6.port())
}
}
}
}