use http::{HeaderValue, StatusCode};
use crate::response::Response;
pub struct ResponseBuilder<Body> {
response: Response<Body>,
}
impl ResponseBuilder<Vec<u8>> {
#[must_use]
pub fn ok() -> Self {
Self::with_status(200)
}
#[must_use]
pub fn with_status(status: u16) -> Self {
let status = StatusCode::from_u16(status).expect(
"ResponseBuilder::with_status called with an out-of-range code (must be 100–999)",
);
assert!(
!status.is_client_error() && !status.is_server_error(),
"ResponseBuilder::with_status called with {status}, but a Response never carries a \
client (4xx) or server (5xx) status — those reach the app as \
Err(HttpError::Http {{ .. }}). Use crux_http::testing::rejection instead."
);
let response = Response::new_with_status(status);
Self { response }
}
}
impl<Body> ResponseBuilder<Body> {
pub fn body<NewBody>(self, body: NewBody) -> ResponseBuilder<NewBody> {
let response = self.response.with_body(body);
ResponseBuilder { response }
}
#[must_use]
pub fn header(
mut self,
name: impl http::header::IntoHeaderName,
value: impl AsRef<str>,
) -> Self {
let value = HeaderValue::from_str(value.as_ref()).expect("invalid header value");
self.response.insert_header(name, value);
self
}
#[must_use]
pub fn append_header(
mut self,
name: impl http::header::IntoHeaderName,
value: impl AsRef<str>,
) -> Self {
let value = HeaderValue::from_str(value.as_ref()).expect("invalid header value");
self.response.append_header(name, value);
self
}
pub fn build(self) -> Response<Body> {
self.response
}
}
#[cfg(test)]
mod tests {
use super::ResponseBuilder;
#[test]
fn builds_any_non_error_status() {
for status in [200, 201, 204, 299, 302, 304] {
assert_eq!(
ResponseBuilder::with_status(status).build().status(),
status
);
}
}
#[test]
#[should_panic(expected = "a Response never carries a client (4xx) or server (5xx) status")]
fn refuses_a_client_error_status() {
let _ = ResponseBuilder::with_status(409);
}
#[test]
#[should_panic(expected = "a Response never carries a client (4xx) or server (5xx) status")]
fn refuses_a_server_error_status() {
let _ = ResponseBuilder::with_status(503);
}
}