mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-01 00:50:32 +01:00
Implement IntoResponse
for Form
(#1095)
This commit is contained in:
parent
93251fa203
commit
2f64064650
5 changed files with 62 additions and 26 deletions
|
@ -9,9 +9,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||
|
||||
- **added:** Support resolving host name via `Forwarded` header in `Host`
|
||||
extractor ([#1078])
|
||||
- **added:** Implement `IntoResponse` for `Form` ([#1095])
|
||||
- **change:** axum's MSRV is now 1.56 ([#1098])
|
||||
|
||||
[#1078]: https://github.com/tokio-rs/axum/pull/1078
|
||||
[#1095]: https://github.com/tokio-rs/axum/pull/1095
|
||||
[#1098]: https://github.com/tokio-rs/axum/pull/1098
|
||||
|
||||
# 0.5.7 (08. June, 2022)
|
||||
|
|
|
@ -39,11 +39,8 @@ pub use crate::Json;
|
|||
pub use crate::Extension;
|
||||
|
||||
#[cfg(feature = "form")]
|
||||
mod form;
|
||||
|
||||
#[cfg(feature = "form")]
|
||||
#[doc(inline)]
|
||||
pub use self::form::Form;
|
||||
#[doc(no_inline)]
|
||||
pub use crate::form::Form;
|
||||
|
||||
#[cfg(feature = "matched-path")]
|
||||
mod matched_path;
|
||||
|
|
|
@ -1,24 +1,23 @@
|
|||
use super::{has_content_type, rejection::*, FromRequest, RequestParts};
|
||||
use crate::body::{Bytes, HttpBody};
|
||||
use crate::extract::{has_content_type, rejection::*, FromRequest, RequestParts};
|
||||
use crate::BoxError;
|
||||
use async_trait::async_trait;
|
||||
use http::Method;
|
||||
use axum_core::response::{IntoResponse, Response};
|
||||
use http::header::CONTENT_TYPE;
|
||||
use http::{Method, StatusCode};
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::Serialize;
|
||||
use std::ops::Deref;
|
||||
|
||||
/// Extractor that deserializes `application/x-www-form-urlencoded` requests
|
||||
/// into some type.
|
||||
/// URL encoded extractor and response.
|
||||
///
|
||||
/// `T` is expected to implement [`serde::Deserialize`].
|
||||
/// # As extractor
|
||||
///
|
||||
/// # Example
|
||||
/// If used as an extractor `Form` will deserialize `application/x-www-form-urlencoded` request
|
||||
/// bodies into some target type via [`serde::Deserialize`].
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use axum::{
|
||||
/// extract::Form,
|
||||
/// routing::post,
|
||||
/// Router,
|
||||
/// };
|
||||
/// ```rust
|
||||
/// use axum::Form;
|
||||
/// use serde::Deserialize;
|
||||
///
|
||||
/// #[derive(Deserialize)]
|
||||
|
@ -27,19 +26,31 @@ use std::ops::Deref;
|
|||
/// password: String,
|
||||
/// }
|
||||
///
|
||||
/// async fn accept_form(form: Form<SignUp>) {
|
||||
/// let sign_up: SignUp = form.0;
|
||||
///
|
||||
/// async fn accept_form(Form(sign_up): Form<SignUp>) {
|
||||
/// // ...
|
||||
/// }
|
||||
///
|
||||
/// let app = Router::new().route("/sign_up", post(accept_form));
|
||||
/// # async {
|
||||
/// # axum::Server::bind(&"".parse().unwrap()).serve(app.into_make_service()).await.unwrap();
|
||||
/// # };
|
||||
/// ```
|
||||
///
|
||||
/// Note that `Content-Type: multipart/form-data` requests are not supported.
|
||||
/// Note that `Content-Type: multipart/form-data` requests are not supported. Use [`Multipart`]
|
||||
/// instead.
|
||||
///
|
||||
/// # As response
|
||||
///
|
||||
/// ```rust
|
||||
/// use axum::Form;
|
||||
/// use serde::Serialize;
|
||||
///
|
||||
/// #[derive(Serialize)]
|
||||
/// struct Payload {
|
||||
/// value: String,
|
||||
/// }
|
||||
///
|
||||
/// async fn handler() -> Form<Payload> {
|
||||
/// Form(Payload { value: "foo".to_owned() })
|
||||
/// }
|
||||
/// ```
|
||||
///
|
||||
/// [`Multipart`]: crate::extract::Multipart
|
||||
#[cfg_attr(docsrs, doc(cfg(feature = "form")))]
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Form<T>(pub T);
|
||||
|
@ -74,6 +85,22 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> IntoResponse for Form<T>
|
||||
where
|
||||
T: Serialize,
|
||||
{
|
||||
fn into_response(self) -> Response {
|
||||
match serde_urlencoded::to_string(&self.0) {
|
||||
Ok(body) => (
|
||||
[(CONTENT_TYPE, mime::APPLICATION_WWW_FORM_URLENCODED.as_ref())],
|
||||
body,
|
||||
)
|
||||
.into_response(),
|
||||
Err(err) => (StatusCode::INTERNAL_SERVER_ERROR, err.to_string()).into_response(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Form<T> {
|
||||
type Target = T;
|
||||
|
|
@ -395,6 +395,8 @@
|
|||
pub(crate) mod macros;
|
||||
|
||||
mod extension;
|
||||
#[cfg(feature = "form")]
|
||||
mod form;
|
||||
#[cfg(feature = "json")]
|
||||
mod json;
|
||||
#[cfg(feature = "headers")]
|
||||
|
@ -434,5 +436,9 @@ pub use self::routing::Router;
|
|||
#[cfg(feature = "headers")]
|
||||
pub use self::typed_header::TypedHeader;
|
||||
|
||||
#[doc(inline)]
|
||||
#[cfg(feature = "headers")]
|
||||
pub use form::Form;
|
||||
|
||||
#[doc(inline)]
|
||||
pub use axum_core::{BoxError, Error};
|
||||
|
|
|
@ -15,6 +15,10 @@ pub use crate::Json;
|
|||
#[cfg(feature = "headers")]
|
||||
pub use crate::TypedHeader;
|
||||
|
||||
#[cfg(feature = "form")]
|
||||
#[doc(no_inline)]
|
||||
pub use crate::form::Form;
|
||||
|
||||
#[doc(no_inline)]
|
||||
pub use crate::Extension;
|
||||
|
||||
|
|
Loading…
Reference in a new issue