diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/lib.rs | 3 | ||||
-rw-r--r-- | src/request.rs | 23 |
2 files changed, 26 insertions, 0 deletions
@@ -1,5 +1,8 @@ //! A lightweight layer on top of [Hyper](https://hyper.rs/) //! to facilitate building web applications. + +#![cfg_attr(docsrs, feature(doc_cfg))] + pub use mime; pub use httpdate; diff --git a/src/request.rs b/src/request.rs index 509e2e7..5b5679d 100644 --- a/src/request.rs +++ b/src/request.rs @@ -96,6 +96,11 @@ pub trait SputnikBody { /// /// The HTML form must embed a hidden input generated with [`crate::request::SputnikParts::csrf_html_input`]. async fn into_form_csrf<T: DeserializeOwned>(self, req: &mut Parts) -> Result<T, CsrfProtectedFormError>; + + /// Attempts to deserialize the request body as JSON. + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + async fn into_json<T: DeserializeOwned>(self) -> Result<T, JsonError>; } fn csrf_token_from_cookies(req: &mut Parts) -> Option<String> { @@ -125,6 +130,13 @@ impl SputnikBody for hyper::Body { None => Err(CsrfProtectedFormError::NoCookie) } } + + #[cfg(feature = "json")] + #[cfg_attr(docsrs, doc(cfg(feature = "json")))] + async fn into_json<T: DeserializeOwned>(self) -> Result<T, JsonError> { + let full_body = self.into_bytes().await?; + Ok(serde_json::from_slice::<T>(&full_body)?) + } } #[derive(Deserialize)] @@ -156,6 +168,17 @@ pub enum FormError { Deserialize(#[from] serde_urlencoded::de::Error), } +#[cfg(feature = "json")] +#[cfg_attr(docsrs, doc(cfg(feature = "json")))] +#[derive(thiserror::Error, Debug)] +pub enum JsonError { + #[error("{0}")] + Body(#[from] BodyError), + + #[error("json deserialize error: {0}")] + Deserialize(#[from] serde_json::Error), +} + #[derive(thiserror::Error, Debug)] pub enum CsrfProtectedFormError { #[error("{0}")] |