1use std::any::type_name_of_val;
9use std::fmt::{Debug, Formatter};
10use crate::body::ResponseBody;
11use crate::fn_trait::FnTrait;
12
13use crate::responder::Responder;
14use crate::{OptionReqBody, RequestContext};
15use async_trait::async_trait;
16use http::Response;
17
18use crate::extract::FromRequest;
19use std::marker::PhantomData;
20
21pub mod handler_decorator;
22pub mod handler_decorator_factory;
23
24#[async_trait]
29pub trait RequestHandler: Send + Sync {
30 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody>;
31}
32
33impl Debug for dyn RequestHandler {
34 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
35 write!(f, "dyn request_handler: {}", type_name_of_val(self))
36 }
37}
38
39#[async_trait]
40impl<T> RequestHandler for Box<T>
41where
42 T: RequestHandler,
43{
44 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
45 (**self).invoke(req, req_body).await
46 }
47}
48
49#[async_trait]
50impl RequestHandler for Box<dyn RequestHandler> {
51 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
52 (**self).invoke(req, req_body).await
53 }
54}
55
56#[async_trait]
57impl RequestHandler for &dyn RequestHandler {
58 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
59 (**self).invoke(req, req_body).await
60 }
61}
62
63pub struct FnHandler<F, Args> {
72 f: F,
73 _phantom: PhantomData<fn(Args)>,
74}
75
76impl<F, Args> Debug for FnHandler<F, Args> {
77 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
78 write!(f, "fn_handler: {}", type_name_of_val(self))
79 }
80}
81
82impl<F, Args> FnHandler<F, Args>
83where
84 F: FnTrait<Args>,
85{
86 fn new(f: F) -> Self {
87 Self { f, _phantom: PhantomData }
88 }
89}
90
91pub fn handler_fn<F, Args>(f: F) -> FnHandler<F, Args>
95where
96 F: FnTrait<Args>,
97{
98 FnHandler::new(f)
99}
100
101#[async_trait]
102impl<F, Args> RequestHandler for FnHandler<F, Args>
103where
104 Args: FromRequest,
107 for<'r> F: FnTrait<Args::Output<'r>>,
110 for<'r> <F as FnTrait<Args::Output<'r>>>::Output: Responder,
113{
114 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
115 let args = match Args::from_request(req, req_body.clone()).await {
116 Ok(args) => args,
117 Err(responder) => return responder.response_to(req),
118 };
119 let responder = self.f.call(args).await;
120 responder.response_to(req)
121 }
122}
123
124#[cfg(test)]
125mod test {
126 use crate::fn_trait::FnTrait;
127 use crate::handler::{FnHandler, RequestHandler};
128
129 use http::Method;
130
131 fn assert_is_fn_handler<H: FnTrait<Args>, Args>(_handler: &FnHandler<H, Args>) {
132 }
134
135 fn assert_is_handler<T: RequestHandler>(_handler: &T) {
136 }
138
139 #[test]
140 fn assert_fn_is_http_handler_1() {
141 async fn get(_header: Method) {}
142
143 let http_handler = FnHandler::new(get);
144 assert_is_fn_handler(&http_handler);
145 assert_is_handler(&http_handler);
146 }
147
148 #[test]
149 fn assert_fn_is_http_handler_2() {
150 async fn get(_header: &Method, _str: String) {}
151
152 let http_handler = FnHandler::new(get);
153 assert_is_fn_handler(&http_handler);
154 assert_is_handler(&http_handler);
155 }
156}