mirror of
https://github.com/tokio-rs/axum.git
synced 2025-01-03 17:52:18 +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`
|
- **added:** Support resolving host name via `Forwarded` header in `Host`
|
||||||
extractor ([#1078])
|
extractor ([#1078])
|
||||||
|
- **added:** Implement `IntoResponse` for `Form` ([#1095])
|
||||||
- **change:** axum's MSRV is now 1.56 ([#1098])
|
- **change:** axum's MSRV is now 1.56 ([#1098])
|
||||||
|
|
||||||
[#1078]: https://github.com/tokio-rs/axum/pull/1078
|
[#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
|
[#1098]: https://github.com/tokio-rs/axum/pull/1098
|
||||||
|
|
||||||
# 0.5.7 (08. June, 2022)
|
# 0.5.7 (08. June, 2022)
|
||||||
|
|
|
@ -39,11 +39,8 @@ pub use crate::Json;
|
||||||
pub use crate::Extension;
|
pub use crate::Extension;
|
||||||
|
|
||||||
#[cfg(feature = "form")]
|
#[cfg(feature = "form")]
|
||||||
mod form;
|
#[doc(no_inline)]
|
||||||
|
pub use crate::form::Form;
|
||||||
#[cfg(feature = "form")]
|
|
||||||
#[doc(inline)]
|
|
||||||
pub use self::form::Form;
|
|
||||||
|
|
||||||
#[cfg(feature = "matched-path")]
|
#[cfg(feature = "matched-path")]
|
||||||
mod matched_path;
|
mod matched_path;
|
||||||
|
|
|
@ -1,24 +1,23 @@
|
||||||
use super::{has_content_type, rejection::*, FromRequest, RequestParts};
|
|
||||||
use crate::body::{Bytes, HttpBody};
|
use crate::body::{Bytes, HttpBody};
|
||||||
|
use crate::extract::{has_content_type, rejection::*, FromRequest, RequestParts};
|
||||||
use crate::BoxError;
|
use crate::BoxError;
|
||||||
use async_trait::async_trait;
|
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::de::DeserializeOwned;
|
||||||
|
use serde::Serialize;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
/// Extractor that deserializes `application/x-www-form-urlencoded` requests
|
/// URL encoded extractor and response.
|
||||||
/// into some type.
|
|
||||||
///
|
///
|
||||||
/// `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
|
/// ```rust
|
||||||
/// use axum::{
|
/// use axum::Form;
|
||||||
/// extract::Form,
|
|
||||||
/// routing::post,
|
|
||||||
/// Router,
|
|
||||||
/// };
|
|
||||||
/// use serde::Deserialize;
|
/// use serde::Deserialize;
|
||||||
///
|
///
|
||||||
/// #[derive(Deserialize)]
|
/// #[derive(Deserialize)]
|
||||||
|
@ -27,19 +26,31 @@ use std::ops::Deref;
|
||||||
/// password: String,
|
/// password: String,
|
||||||
/// }
|
/// }
|
||||||
///
|
///
|
||||||
/// async fn accept_form(form: Form<SignUp>) {
|
/// async fn accept_form(Form(sign_up): Form<SignUp>) {
|
||||||
/// let sign_up: SignUp = form.0;
|
|
||||||
///
|
|
||||||
/// // ...
|
/// // ...
|
||||||
/// }
|
/// }
|
||||||
///
|
|
||||||
/// 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")))]
|
#[cfg_attr(docsrs, doc(cfg(feature = "form")))]
|
||||||
#[derive(Debug, Clone, Copy, Default)]
|
#[derive(Debug, Clone, Copy, Default)]
|
||||||
pub struct Form<T>(pub T);
|
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> {
|
impl<T> Deref for Form<T> {
|
||||||
type Target = T;
|
type Target = T;
|
||||||
|
|
|
@ -395,6 +395,8 @@
|
||||||
pub(crate) mod macros;
|
pub(crate) mod macros;
|
||||||
|
|
||||||
mod extension;
|
mod extension;
|
||||||
|
#[cfg(feature = "form")]
|
||||||
|
mod form;
|
||||||
#[cfg(feature = "json")]
|
#[cfg(feature = "json")]
|
||||||
mod json;
|
mod json;
|
||||||
#[cfg(feature = "headers")]
|
#[cfg(feature = "headers")]
|
||||||
|
@ -434,5 +436,9 @@ pub use self::routing::Router;
|
||||||
#[cfg(feature = "headers")]
|
#[cfg(feature = "headers")]
|
||||||
pub use self::typed_header::TypedHeader;
|
pub use self::typed_header::TypedHeader;
|
||||||
|
|
||||||
|
#[doc(inline)]
|
||||||
|
#[cfg(feature = "headers")]
|
||||||
|
pub use form::Form;
|
||||||
|
|
||||||
#[doc(inline)]
|
#[doc(inline)]
|
||||||
pub use axum_core::{BoxError, Error};
|
pub use axum_core::{BoxError, Error};
|
||||||
|
|
|
@ -15,6 +15,10 @@ pub use crate::Json;
|
||||||
#[cfg(feature = "headers")]
|
#[cfg(feature = "headers")]
|
||||||
pub use crate::TypedHeader;
|
pub use crate::TypedHeader;
|
||||||
|
|
||||||
|
#[cfg(feature = "form")]
|
||||||
|
#[doc(no_inline)]
|
||||||
|
pub use crate::form::Form;
|
||||||
|
|
||||||
#[doc(no_inline)]
|
#[doc(no_inline)]
|
||||||
pub use crate::Extension;
|
pub use crate::Extension;
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue