reqwest_response_ext/
blocking.rs1use super::*;
2
3#[derive(Clone, Debug)]
7pub struct TypedResponse<T, E> {
8 body: bytes::Bytes,
9 result: Result<PhantomData<T>, PhantomData<E>>,
10}
11
12impl<T, E> TypedResponse<T, E>
13where
14 T: de::DeserializeOwned,
15 E: de::DeserializeOwned + From<json::Error>,
16{
17 pub fn try_from_response(response: reqwest::blocking::Response) -> reqwest::Result<Self> {
20 let result = match response.status().is_success() {
21 false => Err(PhantomData),
22 true => Ok(PhantomData),
23 };
24
25 if response.status().is_server_error() {
27 response.error_for_status_ref()?;
28 }
29
30 let body = response.bytes()?;
31
32 Ok(Self { body, result })
33 }
34
35 pub fn bytes(&self) -> &bytes::Bytes {
38 &self.body
39 }
40
41 pub fn text(&self) -> Cow<'_, str> {
44 String::from_utf8_lossy(&self.body)
45 }
46
47 pub fn into_json(self) -> Result<json::Value, json::Value> {
53 let json_err = |e: json::Error| json::json! { e.to_string() };
54 match self.result {
55 Ok(_) => Ok(json::from_slice(&self.body).map_err(json_err)?),
56 Err(_) => Err(json::from_slice(&self.body).map_err(json_err)?),
57 }
58 }
59
60 pub fn into_result(self) -> Result<T, E> {
64 match self.result {
65 Ok(_) => Ok(json::from_slice(&self.body)?),
66 Err(_) => Err(json::from_slice(&self.body)?),
67 }
68 }
69}
70
71pub trait ResponseExt: Sized {
72 fn try_from_response<T, E>(self) -> reqwest::Result<TypedResponse<T, E>>
73 where
74 T: de::DeserializeOwned + Send,
75 E: de::DeserializeOwned + From<json::Error> + Send;
76}
77
78impl ResponseExt for reqwest::blocking::Response {
79 fn try_from_response<T, E>(self) -> reqwest::Result<TypedResponse<T, E>>
80 where
81 T: de::DeserializeOwned + Send,
82 E: de::DeserializeOwned + From<json::Error> + Send,
83 {
84 TypedResponse::try_from_response(self)
85 }
86}