tower_web/response/
response.rs

1use error;
2use response::{Context, Serializer};
3use util::BufStream;
4
5use bytes::Buf;
6use http;
7
8/// Types that can be returned from resources as responses to HTTP requests.
9///
10/// Implementations of `Response` are responsible for encoding the value using
11/// the appropriate content type. The content type may be specific to the type
12/// in question, for example `serde_json::Value` implies a content type of
13/// `application/json`.
14///
15/// Alternatively, the provided `context` may be used to encode the response in
16/// most suitable content-type based on the request context. The content-type is
17/// picked using the following factors:
18///
19/// * The HTTP request's `Accept` header value (not yet implemented).
20/// * Any content type specified by the resource using annotations.
21/// * Serialization formats that the application made available to the resource.
22///
23/// Implementations of `Response` are able to asynchronously stream the response
24/// body if needed. This is done by setting the HTTP response body to a
25/// `BufStream` type that supports streaming.
26pub trait Response {
27    /// Data chunk type.
28    type Buf: Buf;
29
30    /// The HTTP response body type.
31    type Body: BufStream<Item = Self::Buf, Error = ::Error>;
32
33    /// Convert the value into a response future
34    fn into_http<S: Serializer>(self, context: &Context<S>) -> Result<http::Response<Self::Body>, ::Error>;
35}
36
37impl<T> Response for http::Response<T>
38where T: BufStream,
39{
40    type Buf = T::Item;
41    type Body = error::Map<T>;
42
43    fn into_http<S: Serializer>(self, _: &Context<S>) -> Result<http::Response<Self::Body>, ::Error> {
44        Ok(self.map(error::Map::new))
45    }
46}
47
48impl<R, E> Response for Result<R, E>
49where R: Response,
50      E: Into<::Error>,
51{
52    type Buf = R::Buf;
53    type Body = R::Body;
54
55    fn into_http<S: Serializer>(self, context: &Context<S>) -> Result<http::Response<Self::Body>, ::Error> {
56        self.map_err(|err| err.into()).and_then(|resp| resp.into_http(context))
57    }
58}