timvw_rust_runtime/
response.rs1use std::fmt;
2
3use bytes::Bytes;
4use futures_core::Stream;
5use futures_util::TryStreamExt;
6use http_body_util::BodyDataStream;
7use serde::de::DeserializeOwned;
8
9use crate::{Body, Error, HeaderMap, MaybeSend, StatusCode};
10
11pub struct Response {
13 inner: http::Response<Body>,
14}
15
16impl Response {
17 pub fn status(&self) -> StatusCode {
19 self.inner.status()
20 }
21
22 pub fn headers(&self) -> &HeaderMap {
24 self.inner.headers()
25 }
26
27 pub fn headers_mut(&mut self) -> &mut HeaderMap {
29 self.inner.headers_mut()
30 }
31
32 pub async fn bytes(self) -> Result<Bytes, Error> {
34 self.inner
35 .into_body()
36 .collect_bytes()
37 .await
38 .map_err(Error::body)
39 }
40
41 pub async fn text(self) -> Result<String, Error> {
43 let bytes = self.bytes().await?;
44 Ok(match String::from_utf8(bytes.to_vec()) {
45 Ok(text) => text,
46 Err(error) => String::from_utf8_lossy(error.as_bytes()).into_owned(),
47 })
48 }
49
50 pub async fn json<T: DeserializeOwned>(self) -> Result<T, Error> {
52 let bytes = self.bytes().await?;
53 serde_json::from_slice(&bytes).map_err(Error::decode)
54 }
55
56 pub fn bytes_stream(self) -> impl Stream<Item = Result<Bytes, Error>> + MaybeSend + 'static {
58 BodyDataStream::new(self.inner.into_body()).map_err(Error::body)
59 }
60
61 pub fn events(self) -> crate::sse::Events {
64 crate::sse::Events::from_response(self)
65 }
66
67 #[cfg(all(feature = "fs", not(target_family = "wasm")))]
73 pub async fn save_to(self, path: impl AsRef<std::path::Path>) -> Result<u64, Error> {
74 crate::download::save_to(self.bytes_stream(), path.as_ref()).await
75 }
76
77 #[cfg(all(feature = "fs", not(target_family = "wasm")))]
81 pub fn into_async_read(self) -> impl tokio::io::AsyncRead + Send + Unpin + 'static {
82 crate::download::BodyReader::new(self.bytes_stream())
83 }
84
85 pub fn into_http(self) -> http::Response<Body> {
87 self.inner
88 }
89}
90
91impl From<http::Response<Body>> for Response {
92 fn from(inner: http::Response<Body>) -> Self {
93 Self { inner }
94 }
95}
96
97impl fmt::Debug for Response {
98 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
99 f.debug_struct("Response")
100 .field("status", &self.inner.status())
101 .field("headers", self.inner.headers())
102 .finish_non_exhaustive()
103 }
104}