1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
use util::BufStream;

use futures::{Future, Poll};
use http::{Request, Response};
use tower_service::Service;

/// An HTTP service
///
/// This is not intended to be implemented directly. Instead, it is a trait
/// alias of sorts, aliasing `tower_service::Service` trait with `http::Request`
/// and `http::Response` types.
pub trait HttpService: sealed::Service {
    /// Request payload.
    type RequestBody: BufStream;

    /// The HTTP response body type.
    type ResponseBody: BufStream;

    /// The service error type
    type Error;

    /// The future response value.
    type Future: Future<Item = Response<Self::ResponseBody>, Error = Self::Error>;

    /// Returns `Ready` when the service is able to process requests.
    fn poll_http_ready(&mut self) -> Poll<(), Self::Error>;

    /// Process the request and return the response asynchronously.
    fn call_http(&mut self, request: Request<Self::RequestBody>) -> Self::Future;

    /// Wraps `self` with `LiftService`. This provides an implementation of
    /// `Service` for `Self`.
    fn lift(self) -> LiftService<Self>
    where Self: Sized,
    {
        LiftService { inner: self }
    }
}

/// Contains an `HttpService` providing an implementation of `Service`.
#[derive(Debug)]
pub struct LiftService<T> {
    inner: T,
}

impl<T, B1, B2> HttpService for T
where
    T: Service<Request = Request<B1>, Response = Response<B2>>,
    B1: BufStream,
    B2: BufStream,
{
    type RequestBody = B1;
    type ResponseBody = B2;
    type Error = T::Error;
    type Future = T::Future;

    fn poll_http_ready(&mut self) -> Poll<(), T::Error> {
        Service::poll_ready(self)
    }

    fn call_http(&mut self, request: Request<Self::RequestBody>) -> Self::Future {
        Service::call(self, request)
    }
}

impl<T> LiftService<T> {
    /// Return a reference to the underlying `HttpServce`.
    pub fn get_ref(&self) -> &T {
        &self.inner
    }

    /// Return a mutable reference to the underlying `HttpServce`.
    pub fn get_mut(&mut self) -> &mut T {
        &mut self.inner
    }

    /// Consumes `self`, returning the underlying `HttpServce`.
    pub fn into_inner(self) -> T {
        self.inner
    }
}

impl<T> Service for LiftService<T>
where T: HttpService,
{
    type Request = Request<T::RequestBody>;
    type Response = Response<T::ResponseBody>;
    type Error = T::Error;
    type Future = T::Future;

    fn poll_ready(&mut self) -> Poll<(), Self::Error> {
        self.inner.poll_http_ready()
    }

    fn call(&mut self, request: Self::Request) -> Self::Future {
        self.inner.call_http(request)
    }
}

impl<T, B1, B2> sealed::Service for T
where
    T: Service<Request = Request<B1>, Response = Response<B2>>,
    B1: BufStream,
    B2: BufStream
{
}

mod sealed {
    pub trait Service {}
}