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
use crate::{Error, ResponseFuture}; use futures::{future, Future, Stream}; pub trait ResponseContent { type Data; fn convert_response(response: hyper::Response<hyper::Body>) -> ResponseFuture<Self::Data>; } pub trait RequestContent { type Data; fn content_type() -> Option<http::HeaderValue>; fn into_body(self) -> Result<hyper::Body, Error>; } pub struct Empty; impl ResponseContent for Empty { type Data = (); fn convert_response(response: hyper::Response<hyper::Body>) -> ResponseFuture<()> { let (parts, _) = response.into_parts(); Box::new(future::ok(http::Response::from_parts(parts, ()))) } } impl RequestContent for Empty { type Data = (); fn into_body(self) -> Result<hyper::Body, Error> { Ok(hyper::Body::empty()) } fn content_type() -> Option<http::HeaderValue> { None } } pub struct Json<T>(T); impl<T> ResponseContent for Json<T> where T: serde::de::DeserializeOwned + Send + 'static, { type Data = T; fn convert_response(response: hyper::Response<hyper::Body>) -> ResponseFuture<T> { let (parts, body) = response.into_parts(); let fut = body .concat2() .map_err(Error::from) .and_then(|chunk: hyper::Chunk| { serde_json::from_slice(&chunk) .map_err(Error::response) .map(move |body: T| http::Response::from_parts(parts, body)) }); Box::new(fut) } } impl<T> RequestContent for Json<T> where T: serde::Serialize + 'static + Send, { type Data = T; fn content_type() -> Option<http::HeaderValue> { Some(http::HeaderValue::from_static("application/json")) } fn into_body(self) -> Result<hyper::Body, Error> { serde_json::to_vec(&self.0) .map_err(Error::request) .map(|bs| hyper::Body::from(bs)) } }