handler.rs 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242
  1. use std::{
  2. future::Future,
  3. marker::PhantomData,
  4. pin::Pin,
  5. task::{Context, Poll},
  6. };
  7. use futures_core::ready;
  8. use pin_project::pin_project;
  9. use crate::{
  10. errors::DispatchError,
  11. request::{payload::Payload, EventRequest, FromRequest},
  12. response::{EventResponse, Responder},
  13. service::{Service, ServiceFactory, ServiceRequest, ServiceResponse},
  14. util::ready::*,
  15. };
  16. pub trait Handler<T, R>: Clone + 'static + Sync + Send
  17. where
  18. R: Future + Send + Sync,
  19. R::Output: Responder,
  20. {
  21. fn call(&self, param: T) -> R;
  22. }
  23. pub struct HandlerService<H, T, R>
  24. where
  25. H: Handler<T, R>,
  26. T: FromRequest,
  27. R: Future + Sync + Send,
  28. R::Output: Responder,
  29. {
  30. handler: H,
  31. _phantom: PhantomData<(T, R)>,
  32. }
  33. impl<H, T, R> HandlerService<H, T, R>
  34. where
  35. H: Handler<T, R>,
  36. T: FromRequest,
  37. R: Future + Sync + Send,
  38. R::Output: Responder,
  39. {
  40. pub fn new(handler: H) -> Self {
  41. Self {
  42. handler,
  43. _phantom: PhantomData,
  44. }
  45. }
  46. }
  47. impl<H, T, R> Clone for HandlerService<H, T, R>
  48. where
  49. H: Handler<T, R>,
  50. T: FromRequest,
  51. R: Future + Sync + Send,
  52. R::Output: Responder,
  53. {
  54. fn clone(&self) -> Self {
  55. Self {
  56. handler: self.handler.clone(),
  57. _phantom: PhantomData,
  58. }
  59. }
  60. }
  61. impl<F, T, R> ServiceFactory<ServiceRequest> for HandlerService<F, T, R>
  62. where
  63. F: Handler<T, R>,
  64. T: FromRequest,
  65. R: Future + Send + Sync,
  66. R::Output: Responder,
  67. {
  68. type Response = ServiceResponse;
  69. type Error = DispatchError;
  70. type Service = Self;
  71. type Context = ();
  72. type Future = Ready<Result<Self::Service, Self::Error>>;
  73. fn new_service(&self, _: ()) -> Self::Future { ready(Ok(self.clone())) }
  74. }
  75. impl<H, T, R> Service<ServiceRequest> for HandlerService<H, T, R>
  76. where
  77. H: Handler<T, R>,
  78. T: FromRequest,
  79. R: Future + Sync + Send,
  80. R::Output: Responder,
  81. {
  82. type Response = ServiceResponse;
  83. type Error = DispatchError;
  84. type Future = HandlerServiceFuture<H, T, R>;
  85. fn call(&self, req: ServiceRequest) -> Self::Future {
  86. let (req, mut payload) = req.into_parts();
  87. let fut = T::from_request(&req, &mut payload);
  88. HandlerServiceFuture::Extract(fut, Some(req), self.handler.clone())
  89. }
  90. }
  91. #[pin_project(project = HandlerServiceProj)]
  92. pub enum HandlerServiceFuture<H, T, R>
  93. where
  94. H: Handler<T, R>,
  95. T: FromRequest,
  96. R: Future + Sync + Send,
  97. R::Output: Responder,
  98. {
  99. Extract(#[pin] T::Future, Option<EventRequest>, H),
  100. Handle(#[pin] R, Option<EventRequest>),
  101. }
  102. impl<F, T, R> Future for HandlerServiceFuture<F, T, R>
  103. where
  104. F: Handler<T, R>,
  105. T: FromRequest,
  106. R: Future + Sync + Send,
  107. R::Output: Responder,
  108. {
  109. type Output = Result<ServiceResponse, DispatchError>;
  110. fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  111. loop {
  112. match self.as_mut().project() {
  113. HandlerServiceProj::Extract(fut, req, handle) => {
  114. match ready!(fut.poll(cx)) {
  115. Ok(params) => {
  116. let fut = handle.call(params);
  117. let state = HandlerServiceFuture::Handle(fut, req.take());
  118. self.as_mut().set(state);
  119. },
  120. Err(err) => {
  121. let req = req.take().unwrap();
  122. let system_err: DispatchError = err.into();
  123. let res: EventResponse = system_err.into();
  124. return Poll::Ready(Ok(ServiceResponse::new(req, res)));
  125. },
  126. };
  127. },
  128. HandlerServiceProj::Handle(fut, req) => {
  129. let result = ready!(fut.poll(cx));
  130. let req = req.take().unwrap();
  131. let resp = result.respond_to(&req);
  132. return Poll::Ready(Ok(ServiceResponse::new(req, resp)));
  133. },
  134. }
  135. }
  136. }
  137. }
  138. macro_rules! factory_tuple ({ $($param:ident)* } => {
  139. impl<Func, $($param,)* Res> Handler<($($param,)*), Res> for Func
  140. where Func: Fn($($param),*) -> Res + Clone + 'static + Sync + Send,
  141. Res: Future + Sync + Send,
  142. Res::Output: Responder,
  143. {
  144. #[allow(non_snake_case)]
  145. fn call(&self, ($($param,)*): ($($param,)*)) -> Res {
  146. (self)($($param,)*)
  147. }
  148. }
  149. });
  150. macro_rules! tuple_from_req ({$tuple_type:ident, $(($n:tt, $T:ident)),+} => {
  151. #[allow(non_snake_case)]
  152. mod $tuple_type {
  153. use super::*;
  154. #[pin_project::pin_project]
  155. struct FromRequestFutures<$($T: FromRequest),+>($(#[pin] $T::Future),+);
  156. /// FromRequest implementation for tuple
  157. #[doc(hidden)]
  158. #[allow(unused_parens)]
  159. impl<$($T: FromRequest + 'static),+> FromRequest for ($($T,)+)
  160. {
  161. type Error = DispatchError;
  162. type Future = $tuple_type<$($T),+>;
  163. fn from_request(req: &EventRequest, payload: &mut Payload) -> Self::Future {
  164. $tuple_type {
  165. items: <($(Option<$T>,)+)>::default(),
  166. futs: FromRequestFutures($($T::from_request(req, payload),)+),
  167. }
  168. }
  169. }
  170. #[doc(hidden)]
  171. #[pin_project::pin_project]
  172. pub struct $tuple_type<$($T: FromRequest),+> {
  173. items: ($(Option<$T>,)+),
  174. #[pin]
  175. futs: FromRequestFutures<$($T,)+>,
  176. }
  177. impl<$($T: FromRequest),+> Future for $tuple_type<$($T),+>
  178. {
  179. type Output = Result<($($T,)+), DispatchError>;
  180. fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
  181. let mut this = self.project();
  182. let mut ready = true;
  183. $(
  184. if this.items.$n.is_none() {
  185. match this.futs.as_mut().project().$n.poll(cx) {
  186. Poll::Ready(Ok(item)) => this.items.$n = Some(item),
  187. Poll::Pending => ready = false,
  188. Poll::Ready(Err(e)) => return Poll::Ready(Err(e.into())),
  189. }
  190. }
  191. )+
  192. if ready {
  193. Poll::Ready(Ok(
  194. ($(this.items.$n.take().unwrap(),)+)
  195. ))
  196. } else {
  197. Poll::Pending
  198. }
  199. }
  200. }
  201. }
  202. });
  203. factory_tuple! {}
  204. factory_tuple! { A }
  205. factory_tuple! { A B }
  206. factory_tuple! { A B C }
  207. factory_tuple! { A B C D }
  208. factory_tuple! { A B C D E }
  209. #[rustfmt::skip]
  210. mod m {
  211. use super::*;
  212. tuple_from_req!(TupleFromRequest1, (0, A));
  213. tuple_from_req!(TupleFromRequest2, (0, A), (1, B));
  214. tuple_from_req!(TupleFromRequest3, (0, A), (1, B), (2, C));
  215. tuple_from_req!(TupleFromRequest4, (0, A), (1, B), (2, C), (3, D));
  216. tuple_from_req!(TupleFromRequest5, (0, A), (1, B), (2, C), (3, D), (4, E));
  217. }