finchers_core/input/
body.rs1use bytes::Bytes;
2use error::HttpError;
3use http::StatusCode;
4use poll::{Poll, PollResult};
5use std::fmt;
6use std::ops::Deref;
7
8#[cfg(feature = "hyper")]
9use futures::Stream;
10#[cfg(feature = "hyper")]
11use hyper;
12
13pub struct RequestBody {
15 kind: RequestBodyKind,
16}
17
18enum RequestBodyKind {
19 Empty,
20 Once(Option<Bytes>),
21 #[cfg(feature = "hyper")]
22 Hyper(hyper::Body),
23}
24
25impl fmt::Debug for RequestBody {
26 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
27 use self::RequestBodyKind::*;
28 match self.kind {
29 Empty => f.debug_tuple("Empty").finish(),
30 Once(..) => f.debug_tuple("Once").finish(),
31 #[cfg(feature = "hyper")]
32 Hyper(..) => f.debug_tuple("Hyper").finish(),
33 }
34 }
35}
36
37impl RequestBody {
38 pub fn empty() -> RequestBody {
40 RequestBody {
41 kind: RequestBodyKind::Empty,
42 }
43 }
44
45 pub fn once<T>(body: T) -> RequestBody
47 where
48 T: Into<Bytes>,
49 {
50 RequestBody {
51 kind: RequestBodyKind::Once(Some(body.into())),
52 }
53 }
54
55 #[cfg(feature = "hyper")]
57 pub fn from_hyp(body: hyper::Body) -> RequestBody {
58 RequestBody {
59 kind: RequestBodyKind::Hyper(body),
60 }
61 }
62
63 pub fn poll_data(&mut self) -> PollResult<Option<Data>, PollDataError> {
66 use self::RequestBodyKind::*;
67 match self.kind {
68 Empty => Poll::Ready(Ok(None)),
69 Once(ref mut chunk) => Poll::Ready(Ok(chunk.take().map(Data::new))),
70 #[cfg(feature = "hyper")]
71 Hyper(ref mut body) => body.poll()
72 .map(|async| async.map(|chunk_opt| chunk_opt.map(Data::from_hyp)))
73 .map_err(PollDataError::Hyper)
74 .into(),
75 }
76 }
77}
78
79#[derive(Debug)]
81pub struct Data(ChunkType);
82
83#[derive(Debug)]
84enum ChunkType {
85 Shared(Bytes),
86 #[cfg(feature = "hyper")]
87 Hyper(hyper::Chunk),
88}
89
90impl Data {
91 #[allow(missing_docs)]
92 pub fn new<T>(chunk: T) -> Data
93 where
94 T: Into<Bytes>,
95 {
96 Data(ChunkType::Shared(chunk.into()))
97 }
98
99 #[allow(missing_docs)]
100 #[cfg(feature = "hyper")]
101 pub fn from_hyp(chunk: hyper::Chunk) -> Data {
102 Data(ChunkType::Hyper(chunk))
103 }
104}
105
106impl AsRef<[u8]> for Data {
107 fn as_ref(&self) -> &[u8] {
108 match self.0 {
109 ChunkType::Shared(ref b) => b.as_ref(),
110 #[cfg(feature = "hyper")]
111 ChunkType::Hyper(ref c) => c.as_ref(),
112 }
113 }
114}
115
116impl Deref for Data {
117 type Target = [u8];
118
119 fn deref(&self) -> &Self::Target {
120 self.as_ref()
121 }
122}
123
124#[derive(Debug, Fail)]
126pub enum PollDataError {
127 #[allow(missing_docs)]
128 #[cfg(feature = "hyper")]
129 #[fail(display = "during receiving the chunk")]
130 Hyper(hyper::Error),
131
132 #[doc(hidden)]
133 #[fail(display = "dummy for derivation of Fail")]
134 __Dummy(()),
135}
136
137impl HttpError for PollDataError {
138 fn status_code(&self) -> StatusCode {
139 StatusCode::INTERNAL_SERVER_ERROR
140 }
141}