1
0
mirror of https://github.com/fafhrd91/actix-web synced 2024-11-30 10:42:55 +01:00

json method receives plain serialize (#2052)

This commit is contained in:
Rob Ede 2021-03-07 22:11:39 +00:00 committed by GitHub
parent fe0b3f459f
commit 2d3a0d6038
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 47 additions and 8 deletions

View File

@ -4,6 +4,7 @@
### Changed ### Changed
* Feature `cookies` is now optional and disabled by default. [#1981] * Feature `cookies` is now optional and disabled by default. [#1981]
* `ws::hash_key` now returns array. [#2035] * `ws::hash_key` now returns array. [#2035]
* `ResponseBuilder::json` now takes `impl Serialize`. [#2052]
### Removed ### Removed
* re-export of `futures_channel::oneshot::Canceled` is removed from `error` mod. [#1994] * re-export of `futures_channel::oneshot::Canceled` is removed from `error` mod. [#1994]
@ -12,6 +13,7 @@
[#1981]: https://github.com/actix/actix-web/pull/1981 [#1981]: https://github.com/actix/actix-web/pull/1981
[#1994]: https://github.com/actix/actix-web/pull/1994 [#1994]: https://github.com/actix/actix-web/pull/1994
[#2035]: https://github.com/actix/actix-web/pull/2035 [#2035]: https://github.com/actix/actix-web/pull/2035
[#2052]: https://github.com/actix/actix-web/pull/2052
## 3.0.0-beta.3 - 2021-02-10 ## 3.0.0-beta.3 - 2021-02-10

View File

@ -5,7 +5,6 @@ use std::{
convert::TryInto, convert::TryInto,
fmt, fmt,
future::Future, future::Future,
ops,
pin::Pin, pin::Pin,
str, str,
task::{Context, Poll}, task::{Context, Poll},
@ -673,12 +672,8 @@ impl ResponseBuilder {
/// Set a json body and generate `Response` /// Set a json body and generate `Response`
/// ///
/// `ResponseBuilder` can not be used after this call. /// `ResponseBuilder` can not be used after this call.
pub fn json<T>(&mut self, value: T) -> Response pub fn json(&mut self, value: impl Serialize) -> Response {
where match serde_json::to_string(&value) {
T: ops::Deref,
T::Target: Serialize,
{
match serde_json::to_string(&*value) {
Ok(body) => { Ok(body) => {
let contains = if let Some(parts) = parts(&mut self.head, &self.err) { let contains = if let Some(parts) = parts(&mut self.head, &self.err) {
parts.headers.contains_key(header::CONTENT_TYPE) parts.headers.contains_key(header::CONTENT_TYPE)
@ -1007,7 +1002,12 @@ mod tests {
#[test] #[test]
fn test_json() { fn test_json() {
let resp = Response::build(StatusCode::OK).json(vec!["v1", "v2", "v3"]); let resp = Response::Ok().json(vec!["v1", "v2", "v3"]);
let ct = resp.headers().get(CONTENT_TYPE).unwrap();
assert_eq!(ct, HeaderValue::from_static("application/json"));
assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]");
let resp = Response::Ok().json(&["v1", "v2", "v3"]);
let ct = resp.headers().get(CONTENT_TYPE).unwrap(); let ct = resp.headers().get(CONTENT_TYPE).unwrap();
assert_eq!(ct, HeaderValue::from_static("application/json")); assert_eq!(ct, HeaderValue::from_static("application/json"));
assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]"); assert_eq!(resp.body().get_ref(), b"[\"v1\",\"v2\",\"v3\"]");

View File

@ -5,6 +5,7 @@ use std::sync::Arc;
use actix_http::error::{Error, ErrorInternalServerError}; use actix_http::error::{Error, ErrorInternalServerError};
use actix_http::Extensions; use actix_http::Extensions;
use futures_util::future::{err, ok, LocalBoxFuture, Ready}; use futures_util::future::{err, ok, LocalBoxFuture, Ready};
use serde::Serialize;
use crate::dev::Payload; use crate::dev::Payload;
use crate::extract::FromRequest; use crate::extract::FromRequest;
@ -102,6 +103,18 @@ impl<T: ?Sized> From<Arc<T>> for Data<T> {
} }
} }
impl<T> Serialize for Data<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
impl<T: ?Sized + 'static> FromRequest for Data<T> { impl<T: ?Sized + 'static> FromRequest for Data<T> {
type Config = (); type Config = ();
type Error = Error; type Error = Error;

View File

@ -106,6 +106,18 @@ impl<T> ops::DerefMut for Form<T> {
} }
} }
impl<T> Serialize for Form<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
/// See [here](#extractor) for example of usage as an extractor. /// See [here](#extractor) for example of usage as an extractor.
impl<T> FromRequest for Form<T> impl<T> FromRequest for Form<T>
where where

View File

@ -114,6 +114,18 @@ where
} }
} }
impl<T> Serialize for Json<T>
where
T: Serialize,
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.0.serialize(serializer)
}
}
/// Creates response with OK status code, correct content type header, and serialized JSON payload. /// Creates response with OK status code, correct content type header, and serialized JSON payload.
/// ///
/// If serialization failed /// If serialization failed