use std::error::Error as StdError; use std::fmt; use std::future::Future; use std::marker::PhantomData; use crate::body::Body; use crate::service::service::Service; use crate::{Request, Response}; /// Create a `Service` from a function. /// /// # Example /// /// ``` /// use bytes::Bytes; /// use hyper::{body, Request, Response, Version}; /// use http_body_util::Full; /// use hyper::service::service_fn; /// /// let service = service_fn(|req: Request| async move { /// if req.version() == Version::HTTP_11 { /// Ok(Response::new(Full::::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: Fn(Request) -> S, S: Future, { ServiceFn { f, _req: PhantomData, } } /// Service returned by [`service_fn`] pub struct ServiceFn { f: F, _req: PhantomData, } impl Service> for ServiceFn where F: Fn(Request) -> Ret, ReqBody: Body, Ret: Future, E>>, E: Into>, ResBody: Body, { type Response = crate::Response; type Error = E; type Future = Ret; fn call(&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 {}