async_web_client/http/
body.rs

1use futures::future::Either;
2use futures::io::{empty, Cursor, Empty};
3use futures::AsyncRead;
4
5pub trait IntoRequestBody {
6    type RequestBody: AsyncRead + Send;
7    fn into_request_body(self) -> (Self::RequestBody, u64);
8}
9
10pub trait IntoNonUnitRequestBody: IntoRequestBody {}
11
12impl<'a, T: AsRef<[u8]>> IntoNonUnitRequestBody for &'a T {}
13impl<'a, T: AsyncRead + Send> IntoNonUnitRequestBody for (T, u64) {}
14impl IntoNonUnitRequestBody for Vec<u8> {}
15impl IntoNonUnitRequestBody for String {}
16impl<T: IntoNonUnitRequestBody> IntoNonUnitRequestBody for Option<T> {}
17
18impl<'a, T: AsyncRead + Send> IntoRequestBody for (T, u64) {
19    type RequestBody = T;
20    fn into_request_body(self) -> (Self::RequestBody, u64) {
21        (self.0, self.1)
22    }
23}
24
25impl<'a, T: AsRef<[u8]>> IntoRequestBody for &'a T {
26    type RequestBody = &'a [u8];
27    fn into_request_body(self) -> (Self::RequestBody, u64) {
28        let slice = self.as_ref();
29        (slice, slice.len() as u64)
30    }
31}
32
33impl IntoRequestBody for Vec<u8> {
34    type RequestBody = Cursor<Vec<u8>>;
35    fn into_request_body(self) -> (Self::RequestBody, u64) {
36        let len = self.len() as u64;
37        (Cursor::new(self), len)
38    }
39}
40
41impl IntoRequestBody for String {
42    type RequestBody = Cursor<String>;
43    fn into_request_body(self) -> (Self::RequestBody, u64) {
44        let len = self.len() as u64;
45        (Cursor::new(self), len)
46    }
47}
48
49impl IntoRequestBody for () {
50    type RequestBody = Empty;
51    fn into_request_body(self) -> (Self::RequestBody, u64) {
52        (empty(), 0)
53    }
54}
55
56impl<T: IntoRequestBody> IntoRequestBody for Option<T> {
57    type RequestBody = Either<Empty, T::RequestBody>;
58    fn into_request_body(self) -> (Self::RequestBody, u64) {
59        match self {
60            None => (Either::Left(empty()), 0),
61            Some(v) => {
62                let (request_body, len) = v.into_request_body();
63                (Either::Right(request_body), len)
64            }
65        }
66    }
67}
68
69#[cfg(test)]
70mod tests {
71
72    use crate::prelude::*;
73    use http::Request;
74
75    #[test]
76    fn test_send_with_async_read_body() {
77        Request::post("http://postman-echo.com/post")
78            .body((futures::io::Cursor::new(&[3u8]), 1))
79            .unwrap()
80            .send();
81        Request::post("http://postman-echo.com/post")
82            .body(())
83            .unwrap()
84            .send((futures::io::Cursor::new(&[3u8]), 1));
85    }
86    #[test]
87    fn test_send_with_as_ref() {
88        Request::post("http://postman-echo.com/post").body(()).unwrap().send(&[3u8]);
89        Request::post("http://postman-echo.com/post").body(&[3u8]).unwrap().send();
90    }
91    #[test]
92    fn test_send_with_vec() {
93        Request::post("http://postman-echo.com/post").body(()).unwrap().send(vec![1, 2, 3]);
94        Request::post("http://postman-echo.com/post").body(vec![1, 2, 3]).unwrap().send();
95    }
96    #[test]
97    fn test_send_with_string() {
98        Request::post("http://postman-echo.com/post").body(()).unwrap().send("test".to_string());
99        Request::post("http://postman-echo.com/post").body("test".to_string()).unwrap().send();
100    }
101    #[test]
102    fn test_send_with_option() {
103        Request::post("http://postman-echo.com/post").body(()).unwrap().send(Some(&[1, 2, 3]));
104        Request::post("http://postman-echo.com/post").body(Some(&[1, 2, 3])).unwrap().send();
105    }
106}