finchers_runtime/
service.rs

1//! Abstractions for constructing HTTP services.
2//!
3//! The traits in this module have some compatiblity with the traits which will be provided
4//! by Tower and Hyper in the future.
5
6use futures::{self, Future};
7use http::{Request, Response};
8use std::sync::Arc;
9
10/// Trait representing the streaming body of HTTP response.
11pub trait Payload {
12    /// A single chunk of the message body.
13    type Data: AsRef<[u8]> + 'static;
14
15    /// The error which will be returned from `poll_data`.
16    type Error;
17
18    /// Poll a `Data` from this stream.
19    fn poll_data(&mut self) -> futures::Poll<Option<Self::Data>, Self::Error>;
20}
21
22/// A factory of an asynchronous HTTP service.
23pub trait NewHttpService {
24    /// The type of message body in the request.
25    type RequestBody;
26
27    /// The type of message body in the response.
28    type ResponseBody;
29
30    /// The type of error which will be returned from the service.
31    type Error;
32
33    /// The type of `HttpService` to be created by this factory.
34    type Service: HttpService<RequestBody = Self::RequestBody, ResponseBody = Self::ResponseBody, Error = Self::Error>;
35
36    /// The type of error which will occur during creating an HTTP service.
37    type InitError;
38
39    /// A `Future` which will be returned from `new_service` and resolved as a `Service`.
40    type Future: Future<Item = Self::Service, Error = Self::InitError>;
41
42    /// Create a new instance of `HttpService` asynchronously.
43    fn new_service(&self) -> Self::Future;
44}
45
46impl<S: NewHttpService> NewHttpService for Box<S> {
47    type RequestBody = S::RequestBody;
48    type ResponseBody = S::ResponseBody;
49    type Error = S::Error;
50    type Service = S::Service;
51    type Future = S::Future;
52    type InitError = S::InitError;
53
54    fn new_service(&self) -> Self::Future {
55        (**self).new_service()
56    }
57}
58
59impl<S: NewHttpService> NewHttpService for Arc<S> {
60    type RequestBody = S::RequestBody;
61    type ResponseBody = S::ResponseBody;
62    type Error = S::Error;
63    type Service = S::Service;
64    type Future = S::Future;
65    type InitError = S::InitError;
66
67    fn new_service(&self) -> Self::Future {
68        (**self).new_service()
69    }
70}
71
72/// Trait representing an asynchronous function from an HTTP request to an HTTP response.
73pub trait HttpService {
74    /// The type of message body in the request.
75    type RequestBody;
76
77    /// The type of message body in the response.
78    type ResponseBody;
79
80    /// The type of error which will be returned from this service.
81    type Error;
82
83    /// A `Future` which will be returned from `call` and resolved as an HTTP response.
84    type Future: Future<Item = Response<Self::ResponseBody>, Error = Self::Error>;
85
86    /// Apply an HTTP request to this service and get a future which will be resolved as an HTTP
87    /// response.
88    fn call(&mut self, request: Request<Self::RequestBody>) -> Self::Future;
89}
90
91impl<S: HttpService> HttpService for Box<S> {
92    type RequestBody = S::RequestBody;
93    type ResponseBody = S::ResponseBody;
94    type Error = S::Error;
95    type Future = S::Future;
96
97    fn call(&mut self, request: Request<Self::RequestBody>) -> Self::Future {
98        (**self).call(request)
99    }
100}