use std::collections::HashMap;
use crate::core::res_body::ResBody;
use crate::{Request, Response, Result, SilentError};
use async_trait::async_trait;
use http::{Method, StatusCode};
use std::sync::Arc;
#[async_trait]
pub trait Handler: Send + Sync + 'static {
async fn call(&self, _req: Request) -> Result<Response>;
}
#[async_trait]
impl Handler for HashMap<Method, Arc<dyn Handler>> {
async fn call(&self, req: Request) -> Result<Response> {
let method = req.method().clone();
if let Some(handler) = self.get(&method) {
let handler = Arc::clone(handler);
let mut pre_res = Response::empty();
pre_res.state = req.state();
pre_res.copy_from_response(handler.call(req).await?);
return Ok(pre_res);
}
if method == http::Method::HEAD
&& let Some(get_handler) = self.get(&http::Method::GET)
{
let get_handler = Arc::clone(get_handler);
let mut pre_res = Response::empty();
pre_res.state = req.state();
pre_res.copy_from_response(get_handler.call(req).await?);
pre_res.set_body(ResBody::None);
return Ok(pre_res);
}
Err(SilentError::business_error(
StatusCode::METHOD_NOT_ALLOWED,
"method not allowed".to_string(),
))
}
}