From fb3ae9f7dba163411eeeaa355215c5f5e25949aa Mon Sep 17 00:00:00 2001 From: Sergio Benitez Date: Tue, 29 Jun 2021 03:10:33 -0700 Subject: [PATCH] Impl std traits, 'UriDisplay' for 'Json'. The 'Json' type now implements: * Clone * PartialEq * Eq * PartialOrd * Ord * Hash * UriDisplay 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`, previously resolved to `::clone()` but now resolves to ` as Clone>::clone()`. --- core/lib/src/serde/json.rs | 51 ++++++++++++++----------- examples/databases/src/diesel_sqlite.rs | 2 +- 2 files changed, 30 insertions(+), 23 deletions(-) diff --git a/core/lib/src/serde/json.rs b/core/lib/src/serde/json.rs index 0213371d..4bfa6450 100644 --- a/core/lib/src/serde/json.rs +++ b/core/lib/src/serde/json.rs @@ -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` 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/")] +/// fn user(id: usize) -> Json { +/// 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`, 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`, 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` 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/")] -/// fn user(id: usize) -> Json { -/// let user_from_id = User::from(id); -/// /* ... */ -/// Json(user_from_id) -/// } -/// ``` -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Json(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 { } } +impl> fmt::UriDisplay for Json { + fn fmt(&self, f: &mut fmt::Formatter<'_, fmt::Query>) -> std::fmt::Result { + self.0.fmt(f) + } +} + impl From for Json { fn from(value: T) -> Self { Json(value) diff --git a/examples/databases/src/diesel_sqlite.rs b/examples/databases/src/diesel_sqlite.rs index 48370b36..bcf23ae8 100644 --- a/examples/databases/src/diesel_sqlite.rs +++ b/examples/databases/src/diesel_sqlite.rs @@ -38,7 +38,7 @@ async fn create(db: Db, post: Json) -> Result>> { let post_value = post.clone(); db.run(move |conn| { diesel::insert_into(posts::table) - .values(&post_value) + .values(&*post_value) .execute(conn) }).await?;