Line data Source code
1 : use anyhow::Context;
2 : use bytes::Buf;
3 : use hyper::{header, Body, Request, Response, StatusCode};
4 : use serde::{Deserialize, Serialize};
5 :
6 : use super::error::ApiError;
7 :
8 0 : pub async fn json_request<T: for<'de> Deserialize<'de>>(
9 0 : request: &mut Request<Body>,
10 0 : ) -> Result<T, ApiError> {
11 0 : let body = hyper::body::aggregate(request.body_mut())
12 0 : .await
13 0 : .context("Failed to read request body")
14 0 : .map_err(ApiError::BadRequest)?;
15 :
16 0 : if body.remaining() == 0 {
17 0 : return Err(ApiError::BadRequest(anyhow::anyhow!(
18 0 : "missing request body"
19 0 : )));
20 0 : }
21 0 :
22 0 : let mut deser = serde_json::de::Deserializer::from_reader(body.reader());
23 0 :
24 0 : serde_path_to_error::deserialize(&mut deser)
25 0 : // intentionally stringify because the debug version is not helpful in python logs
26 0 : .map_err(|e| anyhow::anyhow!("Failed to parse json request: {e}"))
27 0 : .map_err(ApiError::BadRequest)
28 0 : }
29 :
30 0 : pub fn json_response<T: Serialize>(
31 0 : status: StatusCode,
32 0 : data: T,
33 0 : ) -> Result<Response<Body>, ApiError> {
34 0 : let json = serde_json::to_string(&data)
35 0 : .context("Failed to serialize JSON response")
36 0 : .map_err(ApiError::InternalServerError)?;
37 0 : let response = Response::builder()
38 0 : .status(status)
39 0 : .header(header::CONTENT_TYPE, "application/json")
40 0 : .body(Body::from(json))
41 0 : .map_err(|e| ApiError::InternalServerError(e.into()))?;
42 0 : Ok(response)
43 0 : }
|