use std::ops::{Deref, DerefMut}; use axum::extract::FromRequestParts; use axum::extract::rejection::QueryRejection; use compute_api::responses::GenericAPIError; use http::StatusCode; use http::request::Parts; /// Custom `Query` extractor, so that we can format errors into /// `JsonResponse`. #[derive(Debug, Clone, Copy, Default)] pub(crate) struct Query(pub T); impl FromRequestParts for Query where axum::extract::Query: FromRequestParts, S: Send + Sync, { type Rejection = (StatusCode, axum::Json); async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { match axum::extract::Query::::from_request_parts(parts, state).await { Ok(value) => Ok(Self(value.0)), Err(rejection) => Err(( rejection.status(), axum::Json(GenericAPIError { error: rejection.body_text().to_ascii_lowercase(), }), )), } } } impl Deref for Query { type Target = T; fn deref(&self) -> &Self::Target { &self.0 } } impl DerefMut for Query { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } }