hyper/service/
util.rs

1use std::error::Error as StdError;
2use std::fmt;
3use std::future::Future;
4use std::marker::PhantomData;
5
6use crate::body::Body;
7use crate::service::service::Service;
8use 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/// ```
30pub fn service_fn<F, R, S>(f: F) -> ServiceFn<F, R>
31where
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`]
42pub struct ServiceFn<F, R> {
43    f: F,
44    _req: PhantomData<fn(R)>,
45}
46
47impl<F, ReqBody, Ret, ResBody, E> Service<Request<ReqBody>> for ServiceFn<F, ReqBody>
48where
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
64impl<F, R> fmt::Debug for ServiceFn<F, R> {
65    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66        f.debug_struct("impl Service").finish()
67    }
68}
69
70impl<F, R> Clone for ServiceFn<F, R>
71where
72    F: Clone,
73{
74    fn clone(&self) -> Self {
75        ServiceFn {
76            f: self.f.clone(),
77            _req: PhantomData,
78        }
79    }
80}
81
82impl<F, R> Copy for ServiceFn<F, R> where F: Copy {}