use axum::{extract::FromRequestParts as AxumFromRequestParts, response::IntoResponse as _};
use axum_extra::extract::{Query as AxumQuery, QueryRejection as AxumQueryRejection};
use http::request::Parts;
use crate::{
Registry,
adapters::SerdeAdapter,
openapi::{Operation, ParameterIn, Responses},
request::{FromRequestParts, utils::add_parameters_to_operation},
response::{IntoResponse, Response},
schema::SchemaDeserialize,
};
pub struct Query<T>(pub T);
pub struct QueryRejection(AxumQueryRejection);
impl<S, T> FromRequestParts<S> for Query<T>
where
T: SchemaDeserialize,
S: Send + Sync + 'static,
{
type Rejection = QueryRejection;
fn openapi(operation: &mut Operation, registry: &mut Registry) {
add_parameters_to_operation::<T>(operation, registry, ParameterIn::Query, "query");
}
async fn from_request_parts(parts: &mut Parts, state: &S) -> Result<Self, Self::Rejection> {
<AxumQuery<SerdeAdapter<T>> as AxumFromRequestParts<S>>::from_request_parts(parts, state)
.await
.map(|query| Self(query.0.0))
.map_err(QueryRejection)
}
}
impl IntoResponse for QueryRejection {
fn openapi(_: &mut Registry) -> Responses {
Responses::default()
}
fn into_response(self) -> Response {
self.0.into_response()
}
}