agentkit_http/
response.rs1use bytes::{Bytes, BytesMut};
2use futures_util::{StreamExt, stream::BoxStream};
3use http::{HeaderMap, StatusCode};
4use serde::de::DeserializeOwned;
5
6use crate::HttpError;
7
8pub type BodyStream = BoxStream<'static, Result<Bytes, HttpError>>;
9
10pub struct HttpResponse {
11 status: StatusCode,
12 headers: HeaderMap,
13 final_url: String,
14 body: BodyStream,
15}
16
17impl HttpResponse {
18 pub fn new(
19 status: StatusCode,
20 headers: HeaderMap,
21 final_url: String,
22 body: BodyStream,
23 ) -> Self {
24 Self {
25 status,
26 headers,
27 final_url,
28 body,
29 }
30 }
31
32 pub fn status(&self) -> StatusCode {
33 self.status
34 }
35
36 pub fn headers(&self) -> &HeaderMap {
37 &self.headers
38 }
39
40 pub fn url(&self) -> &str {
41 &self.final_url
42 }
43
44 pub fn bytes_stream(self) -> BodyStream {
45 self.body
46 }
47
48 pub async fn bytes(self) -> Result<Bytes, HttpError> {
49 let mut stream = self.body;
50 let mut buf = BytesMut::new();
51 while let Some(chunk) = stream.next().await {
52 buf.extend_from_slice(&chunk?);
53 }
54 Ok(buf.freeze())
55 }
56
57 pub async fn text(self) -> Result<String, HttpError> {
58 let bytes = self.bytes().await?;
59 String::from_utf8(bytes.to_vec()).map_err(|e| HttpError::Body(Box::new(e)))
60 }
61
62 pub async fn json<T: DeserializeOwned>(self) -> Result<T, HttpError> {
63 let bytes = self.bytes().await?;
64 serde_json::from_slice(&bytes).map_err(HttpError::Deserialize)
65 }
66
67 pub fn error_for_status(self) -> Result<Self, HttpError> {
68 if self.status.is_client_error() || self.status.is_server_error() {
69 Err(HttpError::Other(format!(
70 "response returned status {}",
71 self.status
72 )))
73 } else {
74 Ok(self)
75 }
76 }
77}