backbone_core/
extractors.rs1use axum::{
11 async_trait,
12 extract::{FromRequest, Request},
13 http::header::CONTENT_TYPE,
14 response::{IntoResponse, Response},
15 Form, Json, RequestExt,
16};
17
18pub struct JsonOrForm<T>(pub T);
20
21#[async_trait]
22impl<S, T> FromRequest<S> for JsonOrForm<T>
23where
24 S: Send + Sync,
25 Json<T>: FromRequest<()>,
26 Form<T>: FromRequest<()>,
27 T: 'static,
28{
29 type Rejection = Response;
30
31 async fn from_request(req: Request, _state: &S) -> Result<Self, Self::Rejection> {
32 let is_form = req
33 .headers()
34 .get(CONTENT_TYPE)
35 .and_then(|v| v.to_str().ok())
36 .map(|ct| ct.starts_with("application/x-www-form-urlencoded"))
37 .unwrap_or(false);
38
39 if is_form {
40 let Form(value) = req.extract().await.map_err(IntoResponse::into_response)?;
41 Ok(Self(value))
42 } else {
43 let Json(value) = req.extract().await.map_err(IntoResponse::into_response)?;
45 Ok(Self(value))
46 }
47 }
48}