pavex/response/body/
json.rs

1use bytes::Bytes;
2use http_body_util::Full;
3use mime::APPLICATION_JSON;
4
5use crate::http::HeaderValue;
6
7use super::TypedBody;
8
9/// A [`Response`](crate::Response) body with `Content-Type` set to
10/// `application/json`.
11///
12/// # Example
13///
14/// ```rust
15/// use pavex::{Response, response::body::Json};
16/// use pavex::http::header::CONTENT_TYPE;
17///
18/// #[derive(serde::Serialize)]
19/// struct HomeDetails {
20///     city: String,
21///     postcode: String,
22/// }
23///
24/// let details = HomeDetails {
25///     city: "London".into(),
26///     postcode: "N5 2EF".into(),
27/// };
28/// let json = Json::new(details).expect("Failed to serialize the response body");
29/// let response = Response::ok().set_typed_body(json);
30///
31/// assert_eq!(response.headers()[CONTENT_TYPE], "application/json");
32/// ```
33pub struct Json(Bytes);
34
35impl Json {
36    /// Build a new [`Json`] response by serializing to JSON an instance of type `T`.
37    ///
38    /// It returns an error if serialization fails.
39    pub fn new<T>(value: T) -> Result<Self, JsonSerializationError>
40    where
41        T: serde::Serialize,
42    {
43        let bytes = serde_json::to_vec(&value).map_err(JsonSerializationError)?;
44        Ok(Self(bytes.into()))
45    }
46}
47
48#[derive(Debug, thiserror::Error)]
49#[error(transparent)]
50/// The error returned by [`Json::new`] when the serialization into JSON fails.
51pub struct JsonSerializationError(serde_json::Error);
52
53impl TypedBody for Json {
54    type Body = Full<Bytes>;
55
56    fn content_type(&self) -> HeaderValue {
57        HeaderValue::from_static(APPLICATION_JSON.as_ref())
58    }
59
60    fn body(self) -> Self::Body {
61        Full::new(self.0)
62    }
63}