use axum::{ extract::{ FromRequest, FromRequestParts, Multipart, Path, Query, Request, multipart::MultipartRejection, rejection::{JsonRejection, PathRejection, QueryRejection}, }, http::{StatusCode, request::Parts}, response::{IntoResponse, Response}, }; use serde::de::DeserializeOwned; use crate::errors::{INTERNAL, INVALID_INPUT, refuse}; pub struct MalformedRequest { status: StatusCode, message: String, } impl IntoResponse for MalformedRequest { fn into_response(self) -> Response { let code = if self.status.is_server_error() { INTERNAL } else { INVALID_INPUT }; refuse(self.status, code, self.message) } } impl From for MalformedRequest { fn from(r: JsonRejection) -> Self { Self { status: r.status(), message: r.body_text(), } } } impl From for MalformedRequest { fn from(r: QueryRejection) -> Self { Self { status: r.status(), message: r.body_text(), } } } impl From for MalformedRequest { fn from(r: PathRejection) -> Self { Self { status: r.status(), message: r.body_text(), } } } impl From for MalformedRequest { fn from(r: MultipartRejection) -> Self { Self { status: r.status(), message: r.body_text(), } } } pub struct Upload(pub Multipart); impl FromRequest for Upload where S: Send + Sync, { type Rejection = MalformedRequest; async fn from_request(req: Request, state: &S) -> Result { Ok(Self(Multipart::from_request(req, state).await?)) } } pub struct Body(pub T); impl FromRequest for Body where S: Send + Sync, T: DeserializeOwned, { type Rejection = MalformedRequest; async fn from_request(req: Request, state: &S) -> Result { let axum::Json(v) = axum::Json::::from_request(req, state).await?; Ok(Self(v)) } } pub struct Params(pub T); impl FromRequestParts for Params where S: Send + Sync, T: DeserializeOwned, { type Rejection = MalformedRequest; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let Query(v) = Query::::from_request_parts(parts, state).await?; Ok(Self(v)) } } pub struct PathId(pub T); impl FromRequestParts for PathId where S: Send + Sync, T: DeserializeOwned + Send, { type Rejection = MalformedRequest; async fn from_request_parts(parts: &mut Parts, state: &S) -> Result { let Path(v) = Path::::from_request_parts(parts, state).await?; Ok(Self(v)) } }