use serde::de::DeserializeOwned;
use serde::Serialize;
use std::collections::HashMap;
use std::fmt::{Display, Formatter};
#[cfg(feature = "open-api")]
pub mod openapi;
pub mod route;
pub mod server;
#[derive(Debug)]
pub enum HTTPProtocol {
HTTP10,
HTTP11,
HTTP20,
HTTP30,
Unknown,
}
impl Display for HTTPProtocol {
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
match self {
HTTPProtocol::HTTP10 => f.write_str("HTTP/1.0"),
HTTPProtocol::HTTP11 => f.write_str("HTTP/1.1"),
HTTPProtocol::HTTP20 => f.write_str("HTTP/2.0"),
HTTPProtocol::HTTP30 => f.write_str("HTTP/3.0"),
HTTPProtocol::Unknown => f.write_str("unknown"),
}
}
}
impl Default for HTTPProtocol {
fn default() -> Self {
Self::HTTP11
}
}
impl From<[i32; 2]> for HTTPProtocol {
fn from(proto: [i32; 2]) -> Self {
match proto[0] {
1 if proto[1] == 0 => HTTPProtocol::HTTP10,
1 if proto[1] == 1 => HTTPProtocol::HTTP11,
2 if proto[1] == 0 => HTTPProtocol::HTTP20,
3 if proto[1] == 0 => HTTPProtocol::HTTP30,
_ => HTTPProtocol::Unknown,
}
}
}
#[derive(Debug, Default)]
pub struct Peer {
pub host: Option<String>,
pub port: Option<u32>,
pub family: Option<String>,
}
impl From<HashMap<String, String>> for Peer {
fn from(mut peer: HashMap<String, String>) -> Self {
Self {
host: peer.remove("host"),
port: peer.remove("port").and_then(|v| v.parse::<u32>().ok()),
family: peer.remove("family"),
}
}
}
#[derive(Debug, Default)]
pub struct Request {
pub method: String,
pub path: String,
pub query: String,
pub headers: HashMap<String, String>,
pub stash: HashMap<String, String>,
pub body: Vec<u8>,
pub proto: HTTPProtocol,
pub peer: Peer,
}
impl Request {
pub fn parse<T: DeserializeOwned>(&self) -> Result<T, serde_json::Error> {
serde_json::from_slice::<'_, T>(&self.body)
}
pub fn query<T: DeserializeOwned>(&self) -> Result<T, serde_qs::Error> {
serde_qs::from_str(&self.query)
}
}
#[derive(Debug)]
pub struct Response {
pub status: u32,
pub headers: HashMap<String, String>,
pub body: Vec<u8>,
}
impl<T: Serialize> From<T> for Response {
fn from(data: T) -> Self {
Self {
status: 200,
headers: HashMap::from([(
"content-type".to_string(),
"application/json; charset=utf8".to_string(),
)]),
body: serde_json::to_vec(&data).unwrap(),
}
}
}