finchers_core/output/
body.rs1use bytes::Bytes;
2use futures::Stream;
3use poll::{Poll, PollResult};
4use std::{fmt, io};
5
6pub 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 pub fn empty() -> ResponseBody {
54 ResponseBody { inner: Inner::Empty }
55 }
56
57 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 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 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 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}