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