LCOV - code coverage report
Current view: top level - libs/utils/src/http - json.rs (source / functions) Coverage Total Hit
Test: a2f0f8a80fbf1089336086fa360ce27fa555cb1a.info Lines: 0.0 % 52 0
Test Date: 2024-11-20 17:59:39 Functions: 0.0 % 239 0

            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              : /// Parse a json request body and deserialize it to the type `T`.
       9            0 : pub async fn json_request<T: for<'de> Deserialize<'de>>(
      10            0 :     request: &mut Request<Body>,
      11            0 : ) -> Result<T, ApiError> {
      12            0 :     let body = hyper::body::aggregate(request.body_mut())
      13            0 :         .await
      14            0 :         .context("Failed to read request body")
      15            0 :         .map_err(ApiError::BadRequest)?;
      16              : 
      17            0 :     if body.remaining() == 0 {
      18            0 :         return Err(ApiError::BadRequest(anyhow::anyhow!(
      19            0 :             "missing request body"
      20            0 :         )));
      21            0 :     }
      22            0 : 
      23            0 :     let mut deser = serde_json::de::Deserializer::from_reader(body.reader());
      24            0 : 
      25            0 :     serde_path_to_error::deserialize(&mut deser)
      26            0 :         // intentionally stringify because the debug version is not helpful in python logs
      27            0 :         .map_err(|e| anyhow::anyhow!("Failed to parse json request: {e}"))
      28            0 :         .map_err(ApiError::BadRequest)
      29            0 : }
      30              : 
      31              : /// Parse a json request body and deserialize it to the type `T`. If the body is empty, return `T::default`.
      32            0 : pub async fn json_request_maybe<T: for<'de> Deserialize<'de> + Default>(
      33            0 :     request: &mut Request<Body>,
      34            0 : ) -> Result<T, ApiError> {
      35            0 :     let body = hyper::body::aggregate(request.body_mut())
      36            0 :         .await
      37            0 :         .context("Failed to read request body")
      38            0 :         .map_err(ApiError::BadRequest)?;
      39              : 
      40            0 :     if body.remaining() == 0 {
      41            0 :         return Ok(T::default());
      42            0 :     }
      43            0 : 
      44            0 :     let mut deser = serde_json::de::Deserializer::from_reader(body.reader());
      45            0 : 
      46            0 :     serde_path_to_error::deserialize(&mut deser)
      47            0 :         // intentionally stringify because the debug version is not helpful in python logs
      48            0 :         .map_err(|e| anyhow::anyhow!("Failed to parse json request: {e}"))
      49            0 :         .map_err(ApiError::BadRequest)
      50            0 : }
      51              : 
      52            0 : pub fn json_response<T: Serialize>(
      53            0 :     status: StatusCode,
      54            0 :     data: T,
      55            0 : ) -> Result<Response<Body>, ApiError> {
      56            0 :     let json = serde_json::to_string(&data)
      57            0 :         .context("Failed to serialize JSON response")
      58            0 :         .map_err(ApiError::InternalServerError)?;
      59            0 :     let response = Response::builder()
      60            0 :         .status(status)
      61            0 :         .header(header::CONTENT_TYPE, "application/json")
      62            0 :         .body(Body::from(json))
      63            0 :         .map_err(|e| ApiError::InternalServerError(e.into()))?;
      64            0 :     Ok(response)
      65            0 : }
        

Generated by: LCOV version 2.1-beta