monoio_netreq/
response.rs

1use bytes::Bytes;
2use http::{Extensions, HeaderMap, HeaderValue, StatusCode, Version};
3#[cfg(any(feature = "hyper", feature = "pool-hyper", feature = "hyper-tls"))]
4use http_body_util::BodyExt as HyperBodyExt;
5#[cfg(any(feature = "hyper", feature = "pool-hyper", feature = "hyper-tls"))]
6use hyper::body::Incoming;
7#[cfg(not(feature = "hyper-tls"))]
8use monoio_http::{
9    common::body::{BodyExt, HttpBody},
10    h1::payload::Payload,
11};
12use super::error::Error;
13
14#[cfg(not(feature = "hyper-tls"))]
15pub type Response<P = Payload> = http::response::Response<P>;
16
17#[derive(Debug)]
18pub struct HttpResponse<B> {
19    status: StatusCode,
20    version: Version,
21    headers: HeaderMap<HeaderValue>,
22    extensions: Extensions,
23    body: B,
24}
25
26impl<B> HttpResponse<B> {
27    pub fn status(&self) -> StatusCode {
28        self.status
29    }
30
31    pub fn version(&self) -> Version {
32        self.version
33    }
34
35    pub fn headers(&self) -> &HeaderMap {
36        &self.headers
37    }
38
39    pub fn extensions(&self) -> &Extensions {
40        &self.extensions
41    }
42
43    pub fn raw_body(self) -> B {
44        self.body
45    }
46}
47
48#[cfg(not(feature = "hyper-tls"))]
49impl HttpResponse<HttpBody> {
50    pub(crate) fn new(response: Response<HttpBody>) -> Self {
51        let (parts, body) = response.into_parts();
52
53        HttpResponse {
54            status: parts.status,
55            version: parts.version,
56            headers: parts.headers,
57            extensions: parts.extensions,
58            body,
59        }
60    }
61
62    pub async fn bytes(self) -> Result<Bytes, Error> {
63        let body = self.body;
64        body
65            .bytes()
66            .await
67            .map_err(|e| Error::BytesError(e.to_string()))
68    }
69
70    pub async fn json<T: serde::de::DeserializeOwned>(self) -> Result<T, Error> {
71        let bytes = self
72            .body
73            .bytes()
74            .await
75            .map_err(|e| Error::BytesError(e.to_string()))?;
76        let d = serde_json::from_slice(&bytes).map_err(|e| Error::SerdeDeserializeError(e))?;
77
78        Ok(d)
79    }
80}
81
82#[cfg(any(feature = "hyper", feature = "pool-hyper", feature = "hyper-tls"))]
83impl HttpResponse<Bytes> {
84    pub(crate) async fn hyper_new(response: http::Response<Incoming>) -> Result<Self, Error> {
85        let (parts, byte_stream) = response.into_parts();
86        let body = byte_stream
87            .collect()
88            .await
89            .map_err(|e| Error::BytesError(e.to_string()))?
90            .to_bytes();
91
92        Ok(HttpResponse {
93            status: parts.status,
94            version: parts.version,
95            headers: parts.headers,
96            extensions: parts.extensions,
97            body,
98        })
99    }
100
101    pub async fn json<T: serde::de::DeserializeOwned>(self) -> Result<T, Error> {
102        let d = serde_json::from_slice(&self.body).map_err(|e| Error::SerdeDeserializeError(e))?;
103
104        Ok(d)
105    }
106}