httper/client/
response_future.rs

1use failure::Error;
2use futures::{future, Async, Future, Poll, Stream};
3use hyper;
4use serde::de::DeserializeOwned;
5use serde_json;
6use std::fmt;
7
8pub struct ResponseFuture(
9    pub Box<Future<Item = hyper::Response<hyper::Body>, Error = Error> + Send>,
10);
11
12impl Future for ResponseFuture {
13    type Item = hyper::Response<hyper::Body>;
14    type Error = Error;
15
16    fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
17        let e = match self.0.poll() {
18            Ok(Async::NotReady) => return Ok(Async::NotReady),
19            Ok(Async::Ready(e)) => Ok(e),
20            Err(e) => Err(e),
21        };
22        e.map(Async::Ready)
23    }
24}
25
26impl ResponseFuture {
27    /// Deserialize the response json body into a `T`.
28    /// Returns a Future containing the deserialized body.
29    ///
30    /// # Errors
31    /// Will return Err if the body couldn't be deserialized into a `T`.
32    ///
33    /// # Examples
34    ///
35    /// ```
36    /// extern crate httper;
37    ///
38    /// #[macro_use]
39    /// extern crate serde_derive;
40    ///
41    /// use httper::client::{HttperClient, HttpsClient};
42    ///
43    /// fn main() {
44    ///
45    ///     #[derive(Debug, Deserialize)]
46    ///     struct Data {
47    ///         name: String,
48    ///     }
49    ///
50    ///     let httper_client = HttperClient::new();
51    ///
52    ///     let data = Data {
53    ///         name: "Optimus Prime".to_string(),
54    ///     };
55    ///
56    ///     httper_client.get("https://testing.local").send().json::<Data>();
57    /// }
58    /// ```
59    ///
60    pub fn json<T>(self) -> impl Future<Item = T, Error = Error> + Sized
61    where
62        T: DeserializeOwned + fmt::Debug,
63    {
64        self.0.and_then(|response| {
65            response
66                .into_body()
67                .map_err(Error::from)
68                .concat2()
69                .and_then(|body| {
70                    future::result(serde_json::from_slice::<T>(&body).map_err(Error::from))
71                })
72        })
73    }
74}