graph_http/core/
body_read.rs

1use crate::api_impl::FileConfig;
2use crate::traits::BodyExt;
3use bytes::{Buf, BytesMut};
4use graph_error::{GraphFailure, GraphResult};
5use reqwest::Body;
6use std::io::{BufReader, Read};
7
8pub struct BodyRead {
9    buf: String,
10    bytes_buf: Option<Vec<u8>>,
11    blocking_body: Option<reqwest::blocking::Body>,
12    async_body: Option<Body>,
13}
14
15impl BodyRead {
16    pub fn new(buf: String) -> BodyRead {
17        BodyRead {
18            buf,
19            bytes_buf: None,
20            blocking_body: None,
21            async_body: None,
22        }
23    }
24
25    pub fn has_string_buf(&self) -> bool {
26        self.bytes_buf.is_none() && self.blocking_body.is_none() && self.async_body.is_none()
27    }
28
29    pub fn has_byte_buf(&self) -> bool {
30        self.bytes_buf.is_some()
31    }
32
33    pub fn from_serialize<T: serde::Serialize>(body: &T) -> GraphResult<BodyRead> {
34        let body = serde_json::to_string(body)?;
35        Ok(BodyRead::new(body))
36    }
37
38    pub fn from_read<T: Read>(mut reader: T) -> GraphResult<BodyRead> {
39        let mut byte_buf = Vec::new();
40        reader.read_to_end(&mut byte_buf)?;
41        Ok(BodyRead::from(byte_buf))
42    }
43
44    pub async fn from_async_read<T: tokio::io::AsyncReadExt + Unpin>(
45        mut reader: T,
46    ) -> GraphResult<BodyRead> {
47        let mut byte_buf = Vec::new();
48        reader.read_to_end(&mut byte_buf).await?;
49        Ok(BodyRead::from(reqwest::Body::from(byte_buf)))
50    }
51}
52
53impl From<BodyRead> for Body {
54    fn from(body_read: BodyRead) -> Self {
55        if let Some(body) = body_read.async_body {
56            return body;
57        }
58
59        if let Some(buf) = body_read.bytes_buf {
60            return reqwest::Body::from(buf);
61        }
62
63        reqwest::Body::from(body_read.buf)
64    }
65}
66
67impl From<BodyRead> for reqwest::blocking::Body {
68    fn from(body_read: BodyRead) -> Self {
69        if let Some(body) = body_read.blocking_body {
70            return body;
71        }
72
73        if let Some(buf) = body_read.bytes_buf {
74            return reqwest::blocking::Body::from(buf);
75        }
76
77        reqwest::blocking::Body::from(body_read.buf)
78    }
79}
80
81impl From<String> for BodyRead {
82    fn from(value: String) -> Self {
83        BodyRead::new(value)
84    }
85}
86
87impl<R: Read> TryFrom<BufReader<R>> for BodyRead {
88    type Error = GraphFailure;
89
90    fn try_from(reader: BufReader<R>) -> Result<Self, Self::Error> {
91        BodyRead::from_read(reader)
92    }
93}
94
95impl From<tokio::fs::File> for BodyRead {
96    fn from(file: tokio::fs::File) -> Self {
97        BodyRead {
98            buf: Default::default(),
99            bytes_buf: None,
100            blocking_body: None,
101            async_body: Some(reqwest::Body::from(file)),
102        }
103    }
104}
105
106impl TryFrom<BytesMut> for BodyRead {
107    type Error = GraphFailure;
108
109    fn try_from(bytes_mut: BytesMut) -> Result<Self, Self::Error> {
110        BodyRead::from_read(bytes_mut.reader())
111    }
112}
113
114impl TryFrom<bytes::Bytes> for BodyRead {
115    type Error = GraphFailure;
116
117    fn try_from(bytes: bytes::Bytes) -> Result<Self, Self::Error> {
118        let mut byte_buf = Vec::new();
119        bytes.reader().read_to_end(&mut byte_buf)?;
120        Ok(BodyRead::from(byte_buf))
121    }
122}
123
124impl From<Vec<u8>> for BodyRead {
125    fn from(value: Vec<u8>) -> Self {
126        BodyRead {
127            buf: Default::default(),
128            bytes_buf: Some(value),
129            blocking_body: None,
130            async_body: None,
131        }
132    }
133}
134
135impl From<Body> for BodyRead {
136    fn from(body: Body) -> Self {
137        BodyRead {
138            buf: Default::default(),
139            bytes_buf: None,
140            blocking_body: None,
141            async_body: Some(body),
142        }
143    }
144}
145
146impl From<reqwest::blocking::Body> for BodyRead {
147    fn from(body: reqwest::blocking::Body) -> Self {
148        BodyRead {
149            buf: Default::default(),
150            bytes_buf: None,
151            blocking_body: Some(body),
152            async_body: None,
153        }
154    }
155}
156
157impl TryFrom<FileConfig> for BodyRead {
158    type Error = GraphFailure;
159
160    fn try_from(file_config: FileConfig) -> Result<Self, Self::Error> {
161        BodyRead::try_from(&file_config)
162    }
163}
164
165impl TryFrom<&FileConfig> for BodyRead {
166    type Error = GraphFailure;
167
168    fn try_from(file_config: &FileConfig) -> Result<Self, Self::Error> {
169        let mut file = std::fs::File::open(file_config.path.as_path())?;
170        let mut buf = Vec::new();
171        file.read_to_end(&mut buf)?;
172        Ok(BodyRead::from(buf))
173    }
174}
175
176impl TryFrom<&mut std::fs::File> for BodyRead {
177    type Error = GraphFailure;
178
179    fn try_from(file: &mut std::fs::File) -> Result<Self, Self::Error> {
180        let mut buf = Vec::new();
181        file.read_to_end(&mut buf)?;
182        Ok(BodyRead::from(buf))
183    }
184}
185
186impl BodyExt for BodyRead {
187    fn into_body(self) -> GraphResult<BodyRead> {
188        Ok(self)
189    }
190}