1use bytes::{Buf, Bytes};
2use http::{Request, Response};
3use http_body::Body;
4use http_body_util::BodyExt;
5
6use crate::{EncodeError, PackedRequest, PackedResponse};
7
8#[derive(Debug)]
9pub enum BodyCollectError {
10 Body(Box<dyn std::error::Error + Send + Sync>),
11 Encode(EncodeError),
12}
13
14impl std::fmt::Display for BodyCollectError {
15 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
16 match self {
17 BodyCollectError::Body(err) => write!(f, "body error: {}", err),
18 BodyCollectError::Encode(err) => write!(f, "encode error: {}", err),
19 }
20 }
21}
22
23impl std::error::Error for BodyCollectError {}
24
25pub async fn pack_request<B>(req: Request<B>) -> Result<PackedRequest, BodyCollectError>
26where
27 B: Body,
28 B::Data: Buf,
29 B::Error: std::error::Error + Send + Sync + 'static,
30{
31 let (parts, body) = req.into_parts();
32 let bytes = collect_body(body).await?;
33 let request = Request::from_parts(parts, bytes);
34 PackedRequest::from_request(&request).map_err(BodyCollectError::Encode)
35}
36
37pub async fn pack_response<B>(resp: Response<B>) -> Result<PackedResponse, BodyCollectError>
38where
39 B: Body,
40 B::Data: Buf,
41 B::Error: std::error::Error + Send + Sync + 'static,
42{
43 let (parts, body) = resp.into_parts();
44 let bytes = collect_body(body).await?;
45 let response = Response::from_parts(parts, bytes);
46 PackedResponse::from_response(&response).map_err(BodyCollectError::Encode)
47}
48
49async fn collect_body<B>(body: B) -> Result<Bytes, BodyCollectError>
50where
51 B: Body,
52 B::Data: Buf,
53 B::Error: std::error::Error + Send + Sync + 'static,
54{
55 let collected = body
56 .collect()
57 .await
58 .map_err(|err| BodyCollectError::Body(Box::new(err)))?;
59 Ok(collected.to_bytes())
60}