1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
use bytes::{Bytes, BytesMut};
use http::{Extensions, HeaderMap, HeaderValue, StatusCode, Version};
use monoio_http::{
    common::body::{Body, StreamHint},
    h1::payload::BoxedFramedPayload,
};

pub struct ClientResponse {
    /// The response's status
    status: StatusCode,
    /// The response's version
    version: Version,
    /// The response's headers
    headers: HeaderMap<HeaderValue>,
    /// The response's extensions
    extensions: Extensions,
    /// Payload
    body: BoxedFramedPayload,
}

impl ClientResponse {
    pub fn new(inner: http::Response<BoxedFramedPayload>) -> Self {
        let (head, body) = inner.into_parts();
        Self {
            status: head.status,
            version: head.version,
            headers: head.headers,
            extensions: head.extensions,
            body,
        }
    }

    /// Get the `StatusCode` of this `Response`.
    #[inline]
    pub fn status(&self) -> StatusCode {
        self.status
    }

    /// Get the HTTP `Version` of this `Response`.
    #[inline]
    pub fn version(&self) -> Version {
        self.version
    }

    /// Get the `Headers` of this `Response`.
    #[inline]
    pub fn headers(&self) -> &HeaderMap {
        &self.headers
    }

    /// Get a mutable reference to the `Headers` of this `Response`.
    #[inline]
    pub fn headers_mut(&mut self) -> &mut HeaderMap {
        &mut self.headers
    }

    /// Returns a reference to the associated extensions.
    pub fn extensions(&self) -> &http::Extensions {
        &self.extensions
    }

    /// Returns a mutable reference to the associated extensions.
    pub fn extensions_mut(&mut self) -> &mut http::Extensions {
        &mut self.extensions
    }

    /// Get the full response body as `Bytes`.
    pub async fn bytes(self) -> crate::Result<Bytes> {
        let mut body = self.body;
        if body.stream_hint() == StreamHint::None {
            return Ok(Bytes::new());
        }

        let mut data = BytesMut::new();
        while let Some(res) = body.next_data().await {
            data.extend(res?);
        }
        Ok(data.freeze())
    }

    /// Get raw body(Payload).
    pub fn raw_body(self) -> BoxedFramedPayload {
        self.body
    }

    /// Try to deserialize the response body as JSON.
    // TODO(chihai): use from_reader
    pub async fn json<T: serde::de::DeserializeOwned>(self) -> crate::Result<T> {
        let bytes = self.bytes().await?;
        let d = serde_json::from_slice(&bytes)?;
        Ok(d)
    }
}