1use std::fs::File;
2use std::io::{self, Read, Stdin};
3use std::net::TcpStream;
4
5use crate::body::{Body, BodyReader};
6use crate::http;
7use crate::util::private::Private;
8
9pub struct SendBody<'a> {
20 inner: BodyInner<'a>,
21 ended: bool,
22}
23
24impl<'a> SendBody<'a> {
25 pub fn none() -> SendBody<'static> {
27 BodyInner::None.into()
28 }
29
30 pub fn from_reader(reader: &'a mut dyn Read) -> SendBody<'a> {
32 BodyInner::Reader(reader).into()
33 }
34
35 pub fn from_owned_reader(reader: impl Read + 'static) -> SendBody<'static> {
37 BodyInner::OwnedReader(Box::new(reader)).into()
38 }
39
40 #[cfg(feature = "json")]
42 pub fn from_json(
43 value: &impl serde::ser::Serialize,
44 ) -> Result<SendBody<'static>, crate::Error> {
45 let json = serde_json::to_vec_pretty(value)?;
46 Ok(BodyInner::ByteVec(io::Cursor::new(json)).into())
47 }
48
49 pub(crate) fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
50 let n = match &mut self.inner {
51 BodyInner::None => {
52 return Ok(0);
53 }
54 BodyInner::ByteSlice(v) => {
55 let max = v.len().min(buf.len());
56
57 buf[..max].copy_from_slice(&v[..max]);
58 *v = &v[max..];
59
60 Ok(max)
61 }
62 #[cfg(feature = "json")]
63 BodyInner::ByteVec(v) => v.read(buf),
64 BodyInner::Reader(v) => v.read(buf),
65 BodyInner::OwnedReader(v) => v.read(buf),
66 BodyInner::Body(v) => v.read(buf),
67 }?;
68
69 if n == 0 {
70 self.ended = true;
71 }
72
73 Ok(n)
74 }
75
76 pub(crate) fn body_mode(&self) -> BodyMode {
77 self.inner.body_mode()
78 }
79
80 pub fn into_reader(self) -> impl Sized + io::Read + 'a {
111 ReadAdapter(self)
112 }
113}
114
115struct ReadAdapter<'a>(SendBody<'a>);
116
117impl<'a> io::Read for ReadAdapter<'a> {
118 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
119 self.0.read(buf)
120 }
121}
122
123use http::Response;
124use ureq_proto::BodyMode;
125
126pub trait AsSendBody: Private {
176 #[doc(hidden)]
177 fn as_body(&mut self) -> SendBody;
178}
179
180impl<'a> Private for SendBody<'a> {}
181impl<'a> AsSendBody for SendBody<'a> {
182 fn as_body(&mut self) -> SendBody {
183 SendBody {
184 inner: match &mut self.inner {
185 BodyInner::None => BodyInner::None,
186 BodyInner::ByteSlice(v) => BodyInner::ByteSlice(v),
187 #[cfg(feature = "json")]
188 BodyInner::ByteVec(v) => BodyInner::ByteSlice(v.get_ref()),
189 BodyInner::Reader(v) => BodyInner::Reader(v),
190 BodyInner::Body(v) => BodyInner::Reader(v),
191 BodyInner::OwnedReader(v) => BodyInner::Reader(v),
192 },
193 ended: self.ended,
194 }
195 }
196}
197
198pub(crate) enum BodyInner<'a> {
199 None,
200 ByteSlice(&'a [u8]),
201 #[cfg(feature = "json")]
202 ByteVec(io::Cursor<Vec<u8>>),
203 Body(BodyReader<'a>),
204 Reader(&'a mut dyn Read),
205 OwnedReader(Box<dyn Read>),
206}
207
208impl<'a> BodyInner<'a> {
209 pub fn body_mode(&self) -> BodyMode {
210 match self {
211 BodyInner::None => BodyMode::NoBody,
212 BodyInner::ByteSlice(v) => BodyMode::LengthDelimited(v.len() as u64),
213 #[cfg(feature = "json")]
214 BodyInner::ByteVec(v) => BodyMode::LengthDelimited(v.get_ref().len() as u64),
215 BodyInner::Body(v) => v.body_mode(),
216 BodyInner::Reader(_) => BodyMode::Chunked,
217 BodyInner::OwnedReader(_) => BodyMode::Chunked,
218 }
219 }
220}
221
222impl Private for &[u8] {}
223impl AsSendBody for &[u8] {
224 fn as_body(&mut self) -> SendBody {
225 BodyInner::ByteSlice(self).into()
226 }
227}
228
229impl Private for &str {}
230impl AsSendBody for &str {
231 fn as_body(&mut self) -> SendBody {
232 BodyInner::ByteSlice((*self).as_ref()).into()
233 }
234}
235
236impl Private for String {}
237impl AsSendBody for String {
238 fn as_body(&mut self) -> SendBody {
239 BodyInner::ByteSlice((*self).as_ref()).into()
240 }
241}
242
243impl Private for Vec<u8> {}
244impl AsSendBody for Vec<u8> {
245 fn as_body(&mut self) -> SendBody {
246 BodyInner::ByteSlice((*self).as_ref()).into()
247 }
248}
249
250impl Private for &String {}
251impl AsSendBody for &String {
252 fn as_body(&mut self) -> SendBody {
253 BodyInner::ByteSlice((*self).as_ref()).into()
254 }
255}
256
257impl Private for &Vec<u8> {}
258impl AsSendBody for &Vec<u8> {
259 fn as_body(&mut self) -> SendBody {
260 BodyInner::ByteSlice((*self).as_ref()).into()
261 }
262}
263
264impl Private for &File {}
265impl AsSendBody for &File {
266 fn as_body(&mut self) -> SendBody {
267 BodyInner::Reader(self).into()
268 }
269}
270
271impl Private for &TcpStream {}
272impl AsSendBody for &TcpStream {
273 fn as_body(&mut self) -> SendBody {
274 BodyInner::Reader(self).into()
275 }
276}
277
278impl Private for File {}
279impl AsSendBody for File {
280 fn as_body(&mut self) -> SendBody {
281 BodyInner::Reader(self).into()
282 }
283}
284
285impl Private for TcpStream {}
286impl AsSendBody for TcpStream {
287 fn as_body(&mut self) -> SendBody {
288 BodyInner::Reader(self).into()
289 }
290}
291
292impl Private for Stdin {}
293impl AsSendBody for Stdin {
294 fn as_body(&mut self) -> SendBody {
295 BodyInner::Reader(self).into()
296 }
297}
298
299#[cfg(target_family = "unix")]
303use std::os::unix::net::UnixStream;
304
305#[cfg(target_family = "unix")]
306impl Private for UnixStream {}
307#[cfg(target_family = "unix")]
308impl AsSendBody for UnixStream {
309 fn as_body(&mut self) -> SendBody {
310 BodyInner::Reader(self).into()
311 }
312}
313
314impl<'a> From<BodyInner<'a>> for SendBody<'a> {
315 fn from(inner: BodyInner<'a>) -> Self {
316 SendBody {
317 inner,
318 ended: false,
319 }
320 }
321}
322
323impl Private for Body {}
324impl AsSendBody for Body {
325 fn as_body(&mut self) -> SendBody {
326 BodyInner::Body(self.as_reader()).into()
327 }
328}
329
330impl Private for Response<Body> {}
331impl AsSendBody for Response<Body> {
332 fn as_body(&mut self) -> SendBody {
333 BodyInner::Body(self.body_mut().as_reader()).into()
334 }
335}
336
337impl<const N: usize> Private for &[u8; N] {}
338impl<const N: usize> AsSendBody for &[u8; N] {
339 fn as_body(&mut self) -> SendBody {
340 BodyInner::ByteSlice(self.as_slice()).into()
341 }
342}
343
344impl Private for () {}
345impl AsSendBody for () {
346 fn as_body(&mut self) -> SendBody {
347 BodyInner::None.into()
348 }
349}