Simpify parse-body-based-on-content-type example (#1697)

This commit is contained in:
David Pedersen
2023-01-14 18:39:09 +01:00
committed by GitHub
parent 1be25d9496
commit 00d20eb007
@@ -39,32 +39,25 @@ async fn main() {
.unwrap(); .unwrap();
} }
#[derive(Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
struct Payload { struct Payload {
foo: String, foo: String,
} }
async fn handler(payload: JsonOrForm<Payload>) -> Response { async fn handler(JsonOrForm(payload): JsonOrForm<Payload>) {
match payload { dbg!(payload);
JsonOrForm::Json(payload) => Json(payload).into_response(),
JsonOrForm::Form(payload) => Form(payload).into_response(),
}
} }
enum JsonOrForm<T, K = T> { struct JsonOrForm<T>(T);
Json(T),
Form(K),
}
#[async_trait] #[async_trait]
impl<S, B, T, U> FromRequest<S, B> for JsonOrForm<T, U> impl<S, B, T> FromRequest<S, B> for JsonOrForm<T>
where where
B: Send + 'static, B: Send + 'static,
S: Send + Sync, S: Send + Sync,
Json<T>: FromRequest<(), B>, Json<T>: FromRequest<(), B>,
Form<U>: FromRequest<(), B>, Form<T>: FromRequest<(), B>,
T: 'static, T: 'static,
U: 'static,
{ {
type Rejection = Response; type Rejection = Response;
@@ -75,12 +68,12 @@ where
if let Some(content_type) = content_type { if let Some(content_type) = content_type {
if content_type.starts_with("application/json") { if content_type.starts_with("application/json") {
let Json(payload) = req.extract().await.map_err(IntoResponse::into_response)?; let Json(payload) = req.extract().await.map_err(IntoResponse::into_response)?;
return Ok(Self::Json(payload)); return Ok(Self(payload));
} }
if content_type.starts_with("application/x-www-form-urlencoded") { if content_type.starts_with("application/x-www-form-urlencoded") {
let Form(payload) = req.extract().await.map_err(IntoResponse::into_response)?; let Form(payload) = req.extract().await.map_err(IntoResponse::into_response)?;
return Ok(Self::Form(payload)); return Ok(Self(payload));
} }
} }