hyper/service/
util.rs

1use std::error::Error as StdError;
2use std::fmt;
3use std::future::Future;
4use std::marker::PhantomData;
5use std::task::{Context, Poll};
6
7use crate::body::HttpBody;
8use 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/// ```
28pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
29where
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`]
40pub struct ServiceFn<F, R> {
41    f: F,
42    _req: PhantomData<fn(R)>,
43}
44
45impl<F, ReqBody, Ret, ResBody, E> tower_service::Service<crate::Request<ReqBody>>
46    for ServiceFn<F, ReqBody>
47where
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
58    fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
59        Poll::Ready(Ok(()))
60    }
61
62    fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
63        (self.f)(req)
64    }
65}
66
67impl<F, R> fmt::Debug for ServiceFn<F, R> {
68    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
69        f.debug_struct("impl Service").finish()
70    }
71}
72
73impl<F, R> Clone for ServiceFn<F, R>
74where
75    F: Clone,
76{
77    fn clone(&self) -> Self {
78        ServiceFn {
79            f: self.f.clone(),
80            _req: PhantomData,
81        }
82    }
83}
84
85impl<F, R> Copy for ServiceFn<F, R> where F: Copy {}