1 use std::error::Error as StdError; 2 use std::future::Future; 3 use std::task::{Context, Poll}; 4 5 use crate::body::HttpBody; 6 use crate::{Request, Response}; 7 8 /// An asynchronous function from `Request` to `Response`. 9 pub trait HttpService<ReqBody>: sealed::Sealed<ReqBody> { 10 /// The `HttpBody` body of the `http::Response`. 11 type ResBody: HttpBody; 12 13 /// The error type that can occur within this `Service`. 14 /// 15 /// Note: Returning an `Error` to a hyper server will cause the connection 16 /// to be abruptly aborted. In most cases, it is better to return a `Response` 17 /// with a 4xx or 5xx status code. 18 type Error: Into<Box<dyn StdError + Send + Sync>>; 19 20 /// The `Future` returned by this `Service`. 21 type Future: Future<Output = Result<Response<Self::ResBody>, Self::Error>>; 22 23 #[doc(hidden)] poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>24 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>; 25 26 #[doc(hidden)] call(&mut self, req: Request<ReqBody>) -> Self::Future27 fn call(&mut self, req: Request<ReqBody>) -> Self::Future; 28 } 29 30 impl<T, B1, B2> HttpService<B1> for T 31 where 32 T: tower_service::Service<Request<B1>, Response = Response<B2>>, 33 B2: HttpBody, 34 T::Error: Into<Box<dyn StdError + Send + Sync>>, 35 { 36 type ResBody = B2; 37 38 type Error = T::Error; 39 type Future = T::Future; 40 poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>41 fn poll_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> { 42 tower_service::Service::poll_ready(self, cx) 43 } 44 call(&mut self, req: Request<B1>) -> Self::Future45 fn call(&mut self, req: Request<B1>) -> Self::Future { 46 tower_service::Service::call(self, req) 47 } 48 } 49 50 impl<T, B1, B2> sealed::Sealed<B1> for T 51 where 52 T: tower_service::Service<Request<B1>, Response = Response<B2>>, 53 B2: HttpBody, 54 { 55 } 56 57 mod sealed { 58 pub trait Sealed<T> {} 59 } 60