tower_web/util/http/
service.rs

1use util::BufStream;
2
3use futures::{Future, Poll};
4use http::{Request, Response};
5use tower_service::Service;
6
7/// An HTTP service
8///
9/// This is not intended to be implemented directly. Instead, it is a trait
10/// alias of sorts, aliasing `tower_service::Service` trait with `http::Request`
11/// and `http::Response` types.
12pub trait HttpService: sealed::Service {
13    /// Request payload.
14    type RequestBody: BufStream;
15
16    /// The HTTP response body type.
17    type ResponseBody: BufStream;
18
19    /// The service error type
20    type Error;
21
22    /// The future response value.
23    type Future: Future<Item = Response<Self::ResponseBody>, Error = Self::Error>;
24
25    /// Returns `Ready` when the service is able to process requests.
26    fn poll_http_ready(&mut self) -> Poll<(), Self::Error>;
27
28    /// Process the request and return the response asynchronously.
29    fn call_http(&mut self, request: Request<Self::RequestBody>) -> Self::Future;
30
31    /// Wraps `self` with `LiftService`. This provides an implementation of
32    /// `Service` for `Self`.
33    fn lift(self) -> LiftService<Self>
34    where Self: Sized,
35    {
36        LiftService { inner: self }
37    }
38}
39
40/// Contains an `HttpService` providing an implementation of `Service`.
41#[derive(Debug)]
42pub struct LiftService<T> {
43    inner: T,
44}
45
46impl<T, B1, B2> HttpService for T
47where
48    T: Service<Request = Request<B1>, Response = Response<B2>>,
49    B1: BufStream,
50    B2: BufStream,
51{
52    type RequestBody = B1;
53    type ResponseBody = B2;
54    type Error = T::Error;
55    type Future = T::Future;
56
57    fn poll_http_ready(&mut self) -> Poll<(), T::Error> {
58        Service::poll_ready(self)
59    }
60
61    fn call_http(&mut self, request: Request<Self::RequestBody>) -> Self::Future {
62        Service::call(self, request)
63    }
64}
65
66impl<T> LiftService<T> {
67    /// Return a reference to the underlying `HttpServce`.
68    pub fn get_ref(&self) -> &T {
69        &self.inner
70    }
71
72    /// Return a mutable reference to the underlying `HttpServce`.
73    pub fn get_mut(&mut self) -> &mut T {
74        &mut self.inner
75    }
76
77    /// Consumes `self`, returning the underlying `HttpServce`.
78    pub fn into_inner(self) -> T {
79        self.inner
80    }
81}
82
83impl<T> Service for LiftService<T>
84where T: HttpService,
85{
86    type Request = Request<T::RequestBody>;
87    type Response = Response<T::ResponseBody>;
88    type Error = T::Error;
89    type Future = T::Future;
90
91    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
92        self.inner.poll_http_ready()
93    }
94
95    fn call(&mut self, request: Self::Request) -> Self::Future {
96        self.inner.call_http(request)
97    }
98}
99
100impl<T, B1, B2> sealed::Service for T
101where
102    T: Service<Request = Request<B1>, Response = Response<B2>>,
103    B1: BufStream,
104    B2: BufStream
105{
106}
107
108mod sealed {
109    pub trait Service {}
110}