Line data Source code
1 : use std::ops::{Deref, DerefMut};
2 :
3 : use axum::extract::rejection::JsonRejection;
4 : use axum::extract::{FromRequest, Request};
5 : use compute_api::responses::GenericAPIError;
6 : use http::StatusCode;
7 :
8 : /// Custom `Json` extractor, so that we can format errors into
9 : /// `JsonResponse<GenericAPIError>`.
10 : #[derive(Debug, Clone, Copy, Default)]
11 : pub(crate) struct Json<T>(pub T);
12 :
13 : impl<S, T> FromRequest<S> for Json<T>
14 : where
15 : axum::Json<T>: FromRequest<S, Rejection = JsonRejection>,
16 : S: Send + Sync,
17 : {
18 : type Rejection = (StatusCode, axum::Json<GenericAPIError>);
19 :
20 0 : async fn from_request(req: Request, state: &S) -> Result<Self, Self::Rejection> {
21 0 : match axum::Json::<T>::from_request(req, state).await {
22 0 : Ok(value) => Ok(Self(value.0)),
23 0 : Err(rejection) => Err((
24 0 : rejection.status(),
25 0 : axum::Json(GenericAPIError {
26 0 : error: rejection.body_text().to_lowercase(),
27 0 : }),
28 0 : )),
29 : }
30 0 : }
31 : }
32 :
33 : impl<T> Deref for Json<T> {
34 : type Target = T;
35 :
36 0 : fn deref(&self) -> &Self::Target {
37 0 : &self.0
38 0 : }
39 : }
40 :
41 : impl<T> DerefMut for Json<T> {
42 0 : fn deref_mut(&mut self) -> &mut Self::Target {
43 0 : &mut self.0
44 0 : }
45 : }
|