Skip to main content

oxihttp_server/
response.rs

1//! Response helpers for the OxiHTTP server.
2
3use bytes::Bytes;
4use http::StatusCode;
5use http_body_util::Full;
6
7use oxihttp_core::OxiHttpError;
8
9/// Build a JSON response from a serializable value.
10///
11/// Sets the `Content-Type` header to `application/json`.
12pub fn json_response<T: serde::Serialize>(
13    value: &T,
14) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
15    let body = serde_json::to_vec(value).map_err(|e| OxiHttpError::Json(e.to_string()))?;
16    hyper::Response::builder()
17        .status(StatusCode::OK)
18        .header(http::header::CONTENT_TYPE, "application/json")
19        .body(Full::new(Bytes::from(body)))
20        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
21}
22
23/// Build a JSON response with a custom status code.
24pub fn json_response_with_status<T: serde::Serialize>(
25    status: StatusCode,
26    value: &T,
27) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
28    let body = serde_json::to_vec(value).map_err(|e| OxiHttpError::Json(e.to_string()))?;
29    hyper::Response::builder()
30        .status(status)
31        .header(http::header::CONTENT_TYPE, "application/json")
32        .body(Full::new(Bytes::from(body)))
33        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
34}
35
36/// Build a plain text response.
37pub fn text_response(
38    body: impl Into<String>,
39) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
40    hyper::Response::builder()
41        .status(StatusCode::OK)
42        .header(http::header::CONTENT_TYPE, "text/plain; charset=utf-8")
43        .body(Full::new(Bytes::from(body.into())))
44        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
45}
46
47/// Build an HTML response.
48pub fn html_response(
49    body: impl Into<String>,
50) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
51    hyper::Response::builder()
52        .status(StatusCode::OK)
53        .header(http::header::CONTENT_TYPE, "text/html; charset=utf-8")
54        .body(Full::new(Bytes::from(body.into())))
55        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
56}
57
58/// Build a redirect response (302 Found).
59pub fn redirect_response(location: &str) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
60    hyper::Response::builder()
61        .status(StatusCode::FOUND)
62        .header(http::header::LOCATION, location)
63        .body(Full::new(Bytes::new()))
64        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
65}
66
67/// Build an empty response with a status code.
68pub fn empty_response(status: StatusCode) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
69    hyper::Response::builder()
70        .status(status)
71        .body(Full::new(Bytes::new()))
72        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
73}
74
75/// Build a 204 No Content response.
76pub fn no_content() -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
77    empty_response(StatusCode::NO_CONTENT)
78}
79
80/// Build a 400 Bad Request response with a message.
81pub fn bad_request(msg: impl Into<String>) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
82    hyper::Response::builder()
83        .status(StatusCode::BAD_REQUEST)
84        .header(http::header::CONTENT_TYPE, "text/plain; charset=utf-8")
85        .body(Full::new(Bytes::from(msg.into())))
86        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
87}
88
89/// Build a 500 Internal Server Error response with a message.
90pub fn internal_error(
91    msg: impl Into<String>,
92) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
93    hyper::Response::builder()
94        .status(StatusCode::INTERNAL_SERVER_ERROR)
95        .header(http::header::CONTENT_TYPE, "text/plain; charset=utf-8")
96        .body(Full::new(Bytes::from(msg.into())))
97        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
98}
99
100/// Build an `application/x-www-form-urlencoded` response from a [`oxihttp_core::FormBody`].
101///
102/// The form body is serialized to bytes and returned with status 200 OK and
103/// `Content-Type: application/x-www-form-urlencoded`.
104pub fn form_response(
105    body: oxihttp_core::FormBody,
106) -> Result<hyper::Response<Full<Bytes>>, OxiHttpError> {
107    let bytes = body.build();
108    hyper::Response::builder()
109        .status(StatusCode::OK)
110        .header(
111            http::header::CONTENT_TYPE,
112            "application/x-www-form-urlencoded",
113        )
114        .body(Full::new(bytes))
115        .map_err(|e| OxiHttpError::Http(std::sync::Arc::new(e)))
116}