rust_web_server/request/
body.rs1use std::fmt;
15use std::io::{self, Read};
16use std::sync::{Arc, Mutex};
17
18pub enum Body {
20 Bytes(Vec<u8>),
22 Stream(Arc<Mutex<Box<dyn Read + Send>>>),
26}
27
28impl Body {
29 pub fn empty() -> Self {
31 Body::Bytes(Vec::new())
32 }
33
34 pub fn stream(reader: impl Read + Send + 'static) -> Self {
36 Body::Stream(Arc::new(Mutex::new(Box::new(reader))))
37 }
38
39 pub fn is_stream(&self) -> bool {
41 matches!(self, Body::Stream(_))
42 }
43
44 pub fn as_bytes(&self) -> &[u8] {
46 match self {
47 Body::Bytes(bytes) => bytes,
48 Body::Stream(_) => &[],
49 }
50 }
51
52 pub fn body_bytes(&mut self) -> io::Result<&[u8]> {
56 if let Body::Stream(stream) = self {
57 let mut bytes = Vec::new();
58 stream.lock().map_err(|_| io::Error::other("body stream poisoned"))?.read_to_end(&mut bytes)?;
59 *self = Body::Bytes(bytes);
60 }
61 Ok(self.as_bytes())
62 }
63
64 pub fn into_reader(self) -> Box<dyn Read + Send> {
66 match self {
67 Body::Bytes(bytes) => Box::new(io::Cursor::new(bytes)),
68 Body::Stream(stream) => Box::new(SharedReader(stream)),
69 }
70 }
71
72 pub fn into_vec(mut self) -> io::Result<Vec<u8>> {
74 self.body_bytes()?;
75 match self {
76 Body::Bytes(bytes) => Ok(bytes),
77 Body::Stream(_) => unreachable!("body_bytes turns a stream into bytes"),
78 }
79 }
80
81 pub fn bytes_mut(&mut self) -> io::Result<&mut Vec<u8>> {
83 self.body_bytes()?;
84 match self {
85 Body::Bytes(bytes) => Ok(bytes),
86 Body::Stream(_) => unreachable!("body_bytes turns a stream into bytes"),
87 }
88 }
89}
90
91struct SharedReader(Arc<Mutex<Box<dyn Read + Send>>>);
92
93impl Read for SharedReader {
94 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
95 self.0.lock().map_err(|_| io::Error::other("body stream poisoned"))?.read(buf)
96 }
97}
98
99impl Read for &Body {
102 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
103 match self {
104 Body::Bytes(_) => Ok(0),
105 Body::Stream(stream) => stream.lock().map_err(|_| io::Error::other("body stream poisoned"))?.read(buf),
106 }
107 }
108}
109
110impl Default for Body {
111 fn default() -> Self {
112 Body::empty()
113 }
114}
115
116impl std::ops::Deref for Body {
117 type Target = [u8];
118 fn deref(&self) -> &[u8] {
119 self.as_bytes()
120 }
121}
122
123impl AsRef<[u8]> for Body {
124 fn as_ref(&self) -> &[u8] {
125 self.as_bytes()
126 }
127}
128
129impl Clone for Body {
130 fn clone(&self) -> Self {
131 match self {
132 Body::Bytes(bytes) => Body::Bytes(bytes.clone()),
133 Body::Stream(stream) => Body::Stream(Arc::clone(stream)),
134 }
135 }
136}
137
138impl PartialEq for Body {
140 fn eq(&self, other: &Self) -> bool {
141 match (self, other) {
142 (Body::Bytes(a), Body::Bytes(b)) => a == b,
143 (Body::Stream(a), Body::Stream(b)) => Arc::ptr_eq(a, b),
144 _ => false,
145 }
146 }
147}
148
149impl Eq for Body {}
150
151impl PartialEq<Vec<u8>> for Body {
152 fn eq(&self, other: &Vec<u8>) -> bool {
153 matches!(self, Body::Bytes(bytes) if bytes == other)
154 }
155}
156
157impl PartialEq<[u8]> for Body {
158 fn eq(&self, other: &[u8]) -> bool {
159 matches!(self, Body::Bytes(bytes) if bytes.as_slice() == other)
160 }
161}
162
163impl PartialEq<Body> for Vec<u8> {
164 fn eq(&self, other: &Body) -> bool {
165 other == self
166 }
167}
168
169impl PartialEq<Body> for &[u8] {
170 fn eq(&self, other: &Body) -> bool {
171 other == *self
172 }
173}
174
175impl PartialEq<Body> for [u8] {
176 fn eq(&self, other: &Body) -> bool {
177 other == self
178 }
179}
180
181impl fmt::Debug for Body {
182 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183 match self {
184 Body::Bytes(bytes) => f.debug_tuple("Bytes").field(&bytes.len()).finish(),
185 Body::Stream(_) => f.write_str("Stream"),
186 }
187 }
188}
189
190impl From<Vec<u8>> for Body {
191 fn from(bytes: Vec<u8>) -> Self {
192 Body::Bytes(bytes)
193 }
194}
195
196impl From<&[u8]> for Body {
197 fn from(bytes: &[u8]) -> Self {
198 Body::Bytes(bytes.to_vec())
199 }
200}
201
202impl<const N: usize> From<&[u8; N]> for Body {
203 fn from(bytes: &[u8; N]) -> Self {
204 Body::Bytes(bytes.to_vec())
205 }
206}
207
208impl From<String> for Body {
209 fn from(text: String) -> Self {
210 Body::Bytes(text.into_bytes())
211 }
212}
213
214impl From<&str> for Body {
215 fn from(text: &str) -> Self {
216 Body::Bytes(text.as_bytes().to_vec())
217 }
218}
219
220#[cfg(test)]
221mod tests {
222 use super::Body;
223 use std::io::Read;
224
225 #[test]
226 fn bytes_deref_compare_and_convert() {
227 let body: Body = b"abc".to_vec().into();
228 assert_eq!(3, body.len());
229 assert_eq!(b"abc", &body[..]);
230 assert_eq!(b"abc".to_vec(), body);
231 assert!(body == b"abc".to_vec());
232 assert_eq!(Body::from("abc"), Body::from(&b"abc"[..]));
233 assert!(!body.is_stream());
234 assert_eq!(b"abc".to_vec(), body.clone().into_vec().unwrap());
235 assert!(Body::default().is_empty());
236 }
237
238 #[test]
239 fn a_stream_reads_once_and_becomes_bytes() {
240 let mut body = Body::stream(std::io::Cursor::new(b"streamed".to_vec()));
241 assert!(body.is_stream());
242 assert!(body.is_empty(), "a stream derefs to nothing until read");
243 assert_eq!(b"streamed", body.body_bytes().unwrap());
244 assert!(!body.is_stream());
245 assert_eq!(b"streamed", &body[..]);
246 }
247
248 #[test]
249 fn clones_of_a_stream_share_it() {
250 let body = Body::stream(std::io::Cursor::new(b"0123456789".to_vec()));
251 let other = body.clone();
252 assert_eq!(body, other);
253 let mut first = [0u8; 4];
254 (&body).read_exact(&mut first).unwrap();
255 let mut rest = Vec::new();
256 other.into_reader().read_to_end(&mut rest).unwrap();
257 assert_eq!(b"0123", &first);
258 assert_eq!(b"456789".to_vec(), rest);
259 assert_ne!(Body::stream(std::io::empty()), Body::stream(std::io::empty()));
260 }
261
262 #[test]
263 fn a_failing_stream_is_an_error() {
264 struct Broken;
265 impl Read for Broken {
266 fn read(&mut self, _: &mut [u8]) -> std::io::Result<usize> {
267 Err(std::io::Error::other("client went away"))
268 }
269 }
270 let mut body = Body::stream(Broken);
271 assert!(body.body_bytes().is_err());
272 }
273}