use crate::error::{Error, Never};
use crate::generic::{Encode, Encoder};
use crate::Response;
use futures::{Async, Future, Poll, Stream};
use http::header;
#[derive(Debug)]
pub struct ResponseFuture<T, E> {
inner: T,
encoder: Option<E>,
}
impl<T, E, S> ResponseFuture<T, E>
where
T: Future<Item = Response<S>, Error = crate::Status>,
E: Encoder,
S: Stream<Item = E::Item>,
{
pub fn new(inner: T, encoder: E) -> Self {
ResponseFuture {
inner,
encoder: Some(encoder),
}
}
}
impl<T, E, S> Future for ResponseFuture<T, E>
where
T: Future<Item = Response<S>, Error = crate::Status>,
E: Encoder,
S: Stream<Item = E::Item>,
S::Error: Into<Error>,
{
type Item = http::Response<Encode<E, S>>;
type Error = Never;
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
let response = match self.inner.poll() {
Ok(Async::Ready(response)) => response,
Ok(Async::NotReady) => return Ok(Async::NotReady),
Err(status) => {
let mut response = Response::new(Encode::empty()).into_http();
response.headers_mut().insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static(E::CONTENT_TYPE),
);
status.add_header(response.headers_mut()).unwrap();
return Ok(response.into());
}
};
let mut response = response.into_http();
response.headers_mut().insert(
header::CONTENT_TYPE,
header::HeaderValue::from_static(E::CONTENT_TYPE),
);
let encoder = self.encoder.take().expect("encoder consumed");
let response = response.map(move |body| Encode::response(encoder, body));
Ok(response.into())
}
}