Skip to main content

silent/handler/
handler_trait.rs

1use std::collections::HashMap;
2
3use crate::core::res_body::ResBody;
4use crate::{Request, Response, Result, SilentError};
5use async_trait::async_trait;
6use http::{Method, StatusCode};
7use std::sync::Arc;
8
9#[async_trait]
10pub trait Handler: Send + Sync + 'static {
11    async fn call(&self, _req: Request) -> Result<Response>;
12}
13
14#[async_trait]
15impl Handler for HashMap<Method, Arc<dyn Handler>> {
16    async fn call(&self, req: Request) -> Result<Response> {
17        let method = req.method().clone();
18        // 直接命中匹配的方法
19        if let Some(handler) = self.clone().get(&method) {
20            let mut pre_res = Response::empty();
21            pre_res.state = req.state();
22            pre_res.copy_from_response(handler.call(req).await?);
23            return Ok(pre_res);
24        }
25
26        // 特殊处理:HEAD 无显式处理器时回退到 GET,并清空响应体
27        if method == http::Method::HEAD
28            && let Some(get_handler) = self.clone().get(&http::Method::GET)
29        {
30            let mut pre_res = Response::empty();
31            pre_res.state = req.state();
32            pre_res.copy_from_response(get_handler.call(req).await?);
33            pre_res.set_body(ResBody::None);
34            return Ok(pre_res);
35        }
36
37        Err(SilentError::business_error(
38            StatusCode::METHOD_NOT_ALLOWED,
39            "method not allowed".to_string(),
40        ))
41    }
42}