1use crate::body::ResponseBody;
9use crate::fn_trait::FnTrait;
10
11use crate::responder::Responder;
12use crate::{OptionReqBody, RequestContext};
13use async_trait::async_trait;
14use http::Response;
15
16use crate::extract::FromRequest;
17use std::marker::PhantomData;
18
19pub mod handler_decorator;
20pub mod handler_decorator_factory;
21
22#[async_trait]
27pub trait RequestHandler: Send + Sync {
28 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody>;
29}
30
31#[async_trait]
32impl<T> RequestHandler for Box<T>
33where
34 T: RequestHandler,
35{
36 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
37 (**self).invoke(req, req_body).await
38 }
39}
40
41#[async_trait]
42impl RequestHandler for Box<dyn RequestHandler> {
43 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
44 (**self).invoke(req, req_body).await
45 }
46}
47
48#[async_trait]
49impl RequestHandler for &dyn RequestHandler {
50 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
51 (**self).invoke(req, req_body).await
52 }
53}
54
55pub struct FnHandler<F, Args> {
64 f: F,
65 _phantom: PhantomData<fn(Args)>,
66}
67
68impl<F, Args> FnHandler<F, Args>
69where
70 F: FnTrait<Args>,
71{
72 fn new(f: F) -> Self {
73 Self { f, _phantom: PhantomData }
74 }
75}
76
77pub fn handler_fn<F, Args>(f: F) -> FnHandler<F, Args>
81where
82 F: FnTrait<Args>,
83{
84 FnHandler::new(f)
85}
86
87#[async_trait]
88impl<F, Args> RequestHandler for FnHandler<F, Args>
89where
90 Args: FromRequest,
93 for<'r> F: FnTrait<Args::Output<'r>>,
96 for<'r> <F as FnTrait<Args::Output<'r>>>::Output: Responder,
99{
100 async fn invoke<'server, 'req>(&self, req: &mut RequestContext<'server, 'req>, req_body: OptionReqBody) -> Response<ResponseBody> {
101 let args = match Args::from_request(req, req_body.clone()).await {
102 Ok(args) => args,
103 Err(responder) => return responder.response_to(req),
104 };
105 let responder = self.f.call(args).await;
106 responder.response_to(req)
107 }
108}
109
110#[cfg(test)]
111mod test {
112 use crate::fn_trait::FnTrait;
113 use crate::handler::{FnHandler, RequestHandler};
114
115 use http::Method;
116
117 fn assert_is_fn_handler<H: FnTrait<Args>, Args>(_handler: &FnHandler<H, Args>) {
118 }
120
121 fn assert_is_handler<T: RequestHandler>(_handler: &T) {
122 }
124
125 #[test]
126 fn assert_fn_is_http_handler_1() {
127 async fn get(_header: Method) {}
128
129 let http_handler = FnHandler::new(get);
130 assert_is_fn_handler(&http_handler);
131 assert_is_handler(&http_handler);
132 }
133
134 #[test]
135 fn assert_fn_is_http_handler_2() {
136 async fn get(_header: &Method, _str: String) {}
137
138 let http_handler = FnHandler::new(get);
139 assert_is_fn_handler(&http_handler);
140 assert_is_handler(&http_handler);
141 }
142}