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}