1 use std::error::Error as StdError;
2 use std::fmt;
3 use std::future::Future;
4 use std::marker::PhantomData;
5 use std::task::{Context, Poll};
6 
7 use crate::body::HttpBody;
8 use crate::{Request, Response};
9 
10 /// Create a `Service` from a function.
11 ///
12 /// # Example
13 ///
14 /// ```
15 /// use hyper::{Body, Request, Response, Version};
16 /// use hyper::service::service_fn;
17 ///
18 /// let service = service_fn(|req: Request<Body>| async move {
19 ///     if req.version() == Version::HTTP_11 {
20 ///         Ok(Response::new(Body::from("Hello World")))
21 ///     } else {
22 ///         // Note: it's usually better to return a Response
23 ///         // with an appropriate StatusCode instead of an Err.
24 ///         Err("not HTTP/1.1, abort connection")
25 ///     }
26 /// });
27 /// ```
service_fn<F, R, S>(f: F) -> ServiceFn<F, R> where F: FnMut(Request<R>) -> S, S: Future,28 pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
29 where
30     F: FnMut(Request<R>) -> S,
31     S: Future,
32 {
33     ServiceFn {
34         f,
35         _req: PhantomData,
36     }
37 }
38 
39 /// Service returned by [`service_fn`]
40 pub struct ServiceFn<F, R> {
41     f: F,
42     _req: PhantomData<fn(R)>,
43 }
44 
45 impl<F, ReqBody, Ret, ResBody, E> tower_service::Service<crate::Request<ReqBody>>
46     for ServiceFn<F, ReqBody>
47 where
48     F: FnMut(Request<ReqBody>) -> Ret,
49     ReqBody: HttpBody,
50     Ret: Future<Output = Result<Response<ResBody>, E>>,
51     E: Into<Box<dyn StdError + Send + Sync>>,
52     ResBody: HttpBody,
53 {
54     type Response = crate::Response<ResBody>;
55     type Error = E;
56     type Future = Ret;
57 
poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>58     fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
59         Poll::Ready(Ok(()))
60     }
61 
call(&mut self, req: Request<ReqBody>) -> Self::Future62     fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
63         (self.f)(req)
64     }
65 }
66 
67 impl<F, R> fmt::Debug for ServiceFn<F, R> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result68     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69         f.debug_struct("impl Service").finish()
70     }
71 }
72 
73 impl<F, R> Clone for ServiceFn<F, R>
74 where
75     F: Clone,
76 {
clone(&self) -> Self77     fn clone(&self) -> Self {
78         ServiceFn {
79             f: self.f.clone(),
80             _req: PhantomData,
81         }
82     }
83 }
84 
85 impl<F, R> Copy for ServiceFn<F, R> where F: Copy {}
86