use std::error::Error as StdError; use std::fmt; use std::marker::PhantomData; use crate::body::HttpBody; use crate::common::{task, Future, Poll}; use crate::{Request, Response}; /// Create a `Service` from a function. /// /// # Example /// /// ``` /// use hyper::{Body, Request, Response, Version}; /// use hyper::service::service_fn; /// /// let service = service_fn(|req: Request| async move { /// if req.version() == Version::HTTP_11 { /// Ok(Response::new(Body::from("Hello World"))) /// } else { /// // Note: it's usually better to return a Response /// // with an appropriate StatusCode instead of an Err. /// Err("not HTTP/1.1, abort connection") /// } /// }); /// ``` pub fn service_fn(f: F) -> ServiceFn where F: FnMut(Request) -> S, S: Future, { ServiceFn { f, _req: PhantomData, } } /// Service returned by [`service_fn`] pub struct ServiceFn { f: F, _req: PhantomData, } impl tower_service::Service> for ServiceFn where F: FnMut(Request) -> Ret, ReqBody: HttpBody, Ret: Future, E>>, E: Into>, ResBody: HttpBody, { type Response = crate::Response; type Error = E; type Future = Ret; fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll> { Poll::Ready(Ok(())) } fn call(&mut self, req: Request) -> Self::Future { (self.f)(req) } } impl fmt::Debug for ServiceFn { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { f.debug_struct("impl Service").finish() } } impl Clone for ServiceFn where F: Clone, { fn clone(&self) -> Self { ServiceFn { f: self.f.clone(), _req: PhantomData, } } } impl Copy for ServiceFn where F: Copy {}