128 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Rust
		
	
	
	
	
	
| use std::error::Error as StdError;
 | |
| use std::fmt;
 | |
| use std::marker::PhantomData;
 | |
| 
 | |
| use crate::body::Payload;
 | |
| use crate::common::{Future, Poll, task};
 | |
| use crate::{Request, Response};
 | |
| 
 | |
| /// An asynchronous function from `Request` to `Response`.
 | |
| pub trait Service<ReqBody>: sealed::Sealed<ReqBody> {
 | |
|     /// The `Payload` body of the `http::Response`.
 | |
|     type ResBody: Payload;
 | |
| 
 | |
|     /// The error type that can occur within this `Service`.
 | |
|     ///
 | |
|     /// Note: Returning an `Error` to a hyper server will cause the connection
 | |
|     /// to be abruptly aborted. In most cases, it is better to return a `Response`
 | |
|     /// with a 4xx or 5xx status code.
 | |
|     type Error: Into<Box<dyn StdError + Send + Sync>>;
 | |
| 
 | |
|     /// The `Future` returned by this `Service`.
 | |
|     type Future: Future<Output=Result<Response<Self::ResBody>, Self::Error>>;
 | |
| 
 | |
|     /// Returns `Ready` when the service is able to process requests.
 | |
|     ///
 | |
|     /// The implementation of this method is allowed to return a `Ready` even if
 | |
|     /// the service is not ready to process. In this case, the future returned
 | |
|     /// from `call` will resolve to an error.
 | |
|     fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
 | |
| 
 | |
|     /// Calls this `Service` with a request, returning a `Future` of the response.
 | |
|     fn call(&mut self, req: Request<ReqBody>) -> Self::Future;
 | |
| }
 | |
| 
 | |
| impl<T, B1, B2> Service<B1> for T
 | |
| where 
 | |
|     T: tower_service::Service<Request<B1>, Response = Response<B2>>,
 | |
|     B2: Payload,
 | |
|     T::Error: Into<Box<dyn StdError + Send + Sync>>,
 | |
| {
 | |
|     type ResBody = B2;
 | |
| 
 | |
|     type Error = T::Error;
 | |
|     type Future = T::Future;
 | |
| 
 | |
|     fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
 | |
|         tower_service::Service::poll_ready(self, cx)
 | |
|     }
 | |
| 
 | |
|     fn call(&mut self, req: Request<B1>) -> Self::Future {
 | |
|         tower_service::Service::call(self, req)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<T, B1, B2> sealed::Sealed<B1> for T 
 | |
| where 
 | |
|     T: tower_service::Service<Request<B1>, Response = Response<B2>>,
 | |
|     B2: Payload,
 | |
| {}
 | |
| 
 | |
| mod sealed {
 | |
|     pub trait Sealed<T> {}
 | |
| }
 | |
| 
 | |
| 
 | |
| /// Create a `Service` from a function.
 | |
| ///
 | |
| /// # Example
 | |
| ///
 | |
| /// ```rust
 | |
| /// use hyper::{Body, Request, Response, Version};
 | |
| /// use hyper::service::service_fn;
 | |
| ///
 | |
| /// let service = service_fn(|req: Request<Body>| 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, R, S>(f: F) -> ServiceFn<F, R>
 | |
| where
 | |
|     F: FnMut(Request<R>) -> S,
 | |
|     S: Future,
 | |
| {
 | |
|     ServiceFn {
 | |
|         f,
 | |
|         _req: PhantomData,
 | |
|     }
 | |
| }
 | |
| 
 | |
| // Not exported from crate as this will likely be replaced with `impl Service`.
 | |
| pub struct ServiceFn<F, R> {
 | |
|     f: F,
 | |
|     _req: PhantomData<fn(R)>,
 | |
| }
 | |
| 
 | |
| impl<F, ReqBody, Ret, ResBody, E> tower_service::Service<crate::Request<ReqBody>> for ServiceFn<F, ReqBody>
 | |
| where
 | |
|     F: FnMut(Request<ReqBody>) -> Ret,
 | |
|     ReqBody: Payload,
 | |
|     Ret: Future<Output=Result<Response<ResBody>, E>>,
 | |
|     E: Into<Box<dyn StdError + Send + Sync>>,
 | |
|     ResBody: Payload,
 | |
| {
 | |
|     type Response = crate::Response<ResBody>;
 | |
|     type Error = E;
 | |
|     type Future = Ret;
 | |
| 
 | |
|     fn poll_ready(&mut self, _cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>> {
 | |
|         Poll::Ready(Ok(()))
 | |
|     }
 | |
| 
 | |
|     fn call(&mut self, req: Request<ReqBody>) -> Self::Future {
 | |
|         (self.f)(req)
 | |
|     }
 | |
| }
 | |
| 
 | |
| impl<F, R> fmt::Debug for ServiceFn<F, R> {
 | |
|     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
 | |
|         f.debug_struct("impl Service")
 | |
|             .finish()
 | |
|     }
 | |
| }
 |