finchers_core/output/
body.rs

1use bytes::Bytes;
2use futures::Stream;
3use poll::{Poll, PollResult};
4use std::{fmt, io};
5
6/// An asynchronous stream representing the body of HTTP response.
7pub struct ResponseBody {
8    inner: Inner,
9}
10
11enum Inner {
12    Empty,
13    Once(Option<Bytes>),
14    Stream(Box<Stream<Item = Bytes, Error = io::Error> + Send>),
15}
16
17impl fmt::Debug for ResponseBody {
18    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
19        match self.inner {
20            Inner::Empty => f.debug_tuple("Empty").finish(),
21            Inner::Once(ref bytes) => f.debug_tuple("Once").field(bytes).finish(),
22            Inner::Stream(..) => f.debug_tuple("Stream").finish(),
23        }
24    }
25}
26
27impl Default for ResponseBody {
28    fn default() -> ResponseBody {
29        ResponseBody::empty()
30    }
31}
32
33impl From<()> for ResponseBody {
34    fn from(_: ()) -> ResponseBody {
35        ResponseBody::empty()
36    }
37}
38
39macro_rules! impl_from_once {
40    ($($t:ty),*) => {$(
41        impl From<$t> for ResponseBody {
42            fn from(body: $t) -> ResponseBody {
43                ResponseBody::once(body)
44            }
45        }
46    )*};
47}
48
49impl_from_once!(&'static str, String, &'static [u8], Vec<u8>, Bytes);
50
51impl ResponseBody {
52    /// Create an instance of empty `ResponseBody`.
53    pub fn empty() -> ResponseBody {
54        ResponseBody { inner: Inner::Empty }
55    }
56
57    /// Create an instance of `ResponseBody` from a chunk of bytes.
58    pub fn once<T>(body: T) -> ResponseBody
59    where
60        T: Into<Bytes>,
61    {
62        ResponseBody {
63            inner: Inner::Once(Some(body.into())),
64        }
65    }
66
67    /// Create an instance of `ResponseBody` from a `Stream` of bytes.
68    pub fn wrap_stream<T>(stream: T) -> ResponseBody
69    where
70        T: Stream<Item = Bytes, Error = io::Error> + Send + 'static,
71    {
72        ResponseBody {
73            inner: Inner::Stream(Box::new(stream)),
74        }
75    }
76
77    /// Return the length of bytes if available.
78    pub fn len(&self) -> Option<usize> {
79        match self.inner {
80            Inner::Empty => Some(0),
81            Inner::Once(ref chunk) => chunk.as_ref().map(|c| c.len()),
82            Inner::Stream(..) => None,
83        }
84    }
85
86    /// Poll an element of chunk from this stream.
87    pub fn poll_data(&mut self) -> PollResult<Option<Bytes>, io::Error> {
88        match self.inner {
89            Inner::Empty => Poll::Ready(Ok(None)),
90            Inner::Once(ref mut chunk) => Poll::Ready(Ok(chunk.take())),
91            Inner::Stream(ref mut stream) => stream.poll().into(),
92        }
93    }
94}