Impl std traits, 'UriDisplay<Query>' for 'Json'.

The 'Json' type now implements:

  * Clone
  * PartialEq
  * Eq
  * PartialOrd
  * Ord
  * Hash
  * UriDisplay<Query>

Method calls that resolve to a method in the set of traits above
previously resolved to the `Deref` target. For example, `foo.clone()`,
where `foo: Json<T>`, previously resolved to `<T as Clone>::clone()` but
now resolves to `<Json<T> as Clone>::clone()`.
This commit is contained in:
Sergio Benitez 2021-06-29 03:10:33 -07:00
parent 0e98177973
commit fb3ae9f7db
2 changed files with 30 additions and 23 deletions

View File

@ -32,6 +32,7 @@ use crate::data::{Limits, Data, FromData, Outcome};
use crate::response::{self, Responder, content};
use crate::http::Status;
use crate::form::prelude as form;
use crate::http::uri::fmt;
use serde::{Serialize, Deserialize};
@ -40,14 +41,33 @@ pub use serde_json;
/// The JSON guard: easily consume and return JSON.
///
/// ## Sending JSON
///
/// To respond with serialized JSON data, return a `Json<T>` type, where `T`
/// implements [`Serialize`] from [`serde`]. The content type of the response is
/// set to `application/json` automatically.
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # type User = usize;
/// use rocket::serde::json::Json;
///
/// #[get("/users/<id>")]
/// fn user(id: usize) -> Json<User> {
/// let user_from_id = User::from(id);
/// /* ... */
/// Json(user_from_id)
/// }
/// ```
///
/// ## Receiving JSON
///
/// `Json` is both a data guard and a form guard.
///
/// ### Data Guard
///
/// To parse request body data as JSON , add a `data` route argument with a
/// target type of `Json<T>`, where `T` is some type you'd like to parse from
/// To deserialize request body data as JSON , add a `data` route argument with
/// a target type of `Json<T>`, where `T` is some type you'd like to parse from
/// JSON. `T` must implement [`serde::Deserialize`].
///
/// ```rust
@ -102,26 +122,7 @@ pub use serde_json;
/// [global.limits]
/// json = 5242880
/// ```
///
/// ## Sending JSON
///
/// If you're responding with JSON data, return a `Json<T>` type, where `T`
/// implements [`Serialize`] from [`serde`]. The content type of the response is
/// set to `application/json` automatically.
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # type User = usize;
/// use rocket::serde::json::Json;
///
/// #[get("/users/<id>")]
/// fn user(id: usize) -> Json<User> {
/// let user_from_id = User::from(id);
/// /* ... */
/// Json(user_from_id)
/// }
/// ```
#[derive(Debug)]
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Json<T>(pub T);
/// Error returned by the [`Json`] guard when JSON deserialization fails.
@ -207,6 +208,12 @@ impl<'r, T: Serialize> Responder<'r, 'static> for Json<T> {
}
}
impl<T: fmt::UriDisplay<fmt::Query>> fmt::UriDisplay<fmt::Query> for Json<T> {
fn fmt(&self, f: &mut fmt::Formatter<'_, fmt::Query>) -> std::fmt::Result {
self.0.fmt(f)
}
}
impl<T> From<T> for Json<T> {
fn from(value: T) -> Self {
Json(value)

View File

@ -38,7 +38,7 @@ async fn create(db: Db, post: Json<Post>) -> Result<Created<Json<Post>>> {
let post_value = post.clone();
db.run(move |conn| {
diesel::insert_into(posts::table)
.values(&post_value)
.values(&*post_value)
.execute(conn)
}).await?;