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