hyper/service/
util.rs

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