use http_body_util::BodyExt;
use hyper::body::Bytes;
use std::convert::Infallible;
pub type BoxBody = http_body_util::combinators::BoxBody<Bytes, Infallible>;
pub struct CollectedResponse {
pub status: hyper::StatusCode,
pub headers: Vec<(String, String)>,
pub body: Vec<u8>,
}
impl CollectedResponse {
pub async fn collect(response: hyper::Response<BoxBody>) -> Self {
let (parts, body) = response.into_parts();
let bytes = body
.collect()
.await
.expect("BoxBody's error type is Infallible")
.to_bytes();
let headers = parts
.headers
.iter()
.filter_map(|(k, v)| v.to_str().ok().map(|v| (k.to_string(), v.to_owned())))
.collect();
Self {
status: parts.status,
headers,
body: bytes.to_vec(),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use http_body_util::Full;
#[tokio::test]
async fn collect_reads_status_headers_and_body() {
let response = hyper::Response::builder()
.status(201)
.header("x-custom", "yes")
.body(
Full::new(Bytes::from_static(b"hello"))
.map_err(|e| match e {})
.boxed(),
)
.unwrap();
let collected = CollectedResponse::collect(response).await;
assert_eq!(collected.status, hyper::StatusCode::CREATED);
assert_eq!(collected.body, b"hello");
assert!(
collected
.headers
.iter()
.any(|(k, v)| k == "x-custom" && v == "yes")
);
}
}