wasi_http_client/
response.rs1use anyhow::{anyhow, Result};
2#[cfg(feature = "json")]
3use serde::de::DeserializeOwned;
4use std::collections::HashMap;
5use wasi::http::types::{IncomingBody, IncomingResponse};
6use wasi::io::streams::{InputStream, StreamError};
7
8pub struct Response {
9 status: u16,
10 headers: HashMap<String, String>,
11 input_stream: InputStream,
13 _incoming_body: IncomingBody,
14}
15
16impl Response {
17 pub(crate) fn new(incoming_response: IncomingResponse) -> Result<Self> {
18 let status = incoming_response.status();
19
20 let mut headers: HashMap<String, String> = HashMap::new();
21 let headers_handle = incoming_response.headers();
22 for (key, value) in headers_handle.entries() {
23 headers.insert(key, String::from_utf8(value)?);
24 }
25 drop(headers_handle);
26
27 let incoming_body = incoming_response.consume().unwrap();
29 drop(incoming_response);
30
31 let input_stream = incoming_body.stream().unwrap();
33 Ok(Self {
34 status,
35 headers,
36 input_stream,
37 _incoming_body: incoming_body,
38 })
39 }
40
41 pub fn status(&self) -> u16 {
43 self.status
44 }
45
46 pub fn headers(&self) -> &HashMap<String, String> {
48 &self.headers
49 }
50
51 pub fn chunk(&self, len: u64) -> Result<Option<Vec<u8>>> {
55 match self.input_stream.blocking_read(len) {
56 Ok(c) => Ok(Some(c)),
57 Err(StreamError::Closed) => Ok(None),
58 Err(e) => Err(anyhow!("input_stream read failed: {e:?}"))?,
59 }
60 }
61
62 pub fn body(self) -> Result<Vec<u8>> {
66 let mut body = Vec::new();
67 while let Some(mut chunk) = self.chunk(1024 * 1024)? {
68 body.append(&mut chunk);
69 }
70 Ok(body)
71 }
72
73 #[cfg(feature = "json")]
96 #[cfg_attr(docsrs, doc(cfg(feature = "json")))]
97 pub fn json<T: DeserializeOwned>(self) -> Result<T> {
98 Ok(serde_json::from_slice(self.body()?.as_ref())?)
99 }
100}