silent 2.16.1

Silent Web Framework
Documentation
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();
        // 直接命中匹配的方法(直接引用,不克隆 HashMap)
        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);
        }

        // 特殊处理:HEAD 无显式处理器时回退到 GET,并清空响应体
        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(),
        ))
    }
}