Skip to content

Commit

Permalink
Change default, and use MsgPack in place of Named
Browse files Browse the repository at this point in the history
  • Loading branch information
the10thWiz committed Aug 10, 2024
1 parent c1d2489 commit 02ce87a
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 39 deletions.
57 changes: 23 additions & 34 deletions core/lib/src/serde/msgpack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,25 @@ pub use rmp_serde::decode::Error;
///
/// ## Sending MessagePack
///
/// To respond with serialized MessagePack data, return either [`Named<T>`] or
/// To respond with serialized MessagePack data, return either [`MsgPack<T>`] or
/// [`Compact<T>`] from your handler. `T` must implement [`serde::Serialize`].
///
/// Currently, returning `MsgPack<T>` is equivalent to returning `Compact<T>`,
/// but you should prefer to use an explicit option as this default may change
/// in the future.
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # type User = usize;
/// use rocket::serde::msgpack::MsgPack;
///
/// #[get("/users/<id>")]
/// fn user(id: usize) -> MsgPack<User> {
/// let user_from_id = User::from(id);
/// /* ... */
/// MsgPack(user_from_id)
/// }
/// ```
///
/// The differences between [`MsgPack<T>`] and [`Compact<T>`] are documented on
/// [`Compact<T>`]. In most cases, [`MsgPack<T>`] is preferable, although compact
/// was the default prior to Rocket version 0.6.
///
/// ## Receiving MessagePack
///
Expand Down Expand Up @@ -113,7 +126,7 @@ pub use rmp_serde::decode::Error;
/// msgpack = 5242880
/// ```
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct MsgPack<T, const COMPACT: bool = true>(pub T);
pub struct MsgPack<T, const COMPACT: bool = false>(pub T);

/// Serializes responses in a compact MesagePack format, where structs are
/// serialized as arrays of their field values.
Expand Down Expand Up @@ -141,32 +154,6 @@ pub struct MsgPack<T, const COMPACT: bool = true>(pub T);
/// NOT prevent named requests from being accepted.
pub type Compact<T> = MsgPack<T, true>;

/// Serializes responses in a named MessagePack format, where structs are
/// serialized as maps of their field names and values.
///
/// To respond with named MessagePack data, return a `Named<T>` type,
/// where `T` implements [`Serialize`] from [`serde`]. The content type of the
/// response is set to `application/msgpack` automatically.
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// # type User = usize;
/// use rocket::serde::msgpack;
///
/// #[get("/users/<id>")]
/// fn user(id: usize) -> msgpack::Named<User> {
/// let user_from_id = User::from(id);
/// /* ... */
/// msgpack::MsgPack(user_from_id)
/// }
/// ```
///
/// Prefer using [`MsgPack<T>`] for request guards, as the named/compact
/// distinction is not relevant for request data - the correct option is
/// implemented automatically. Using [`Named<T>`] as a request guard will
/// NOT prevent compact requests from being accepted.
pub type Named<T> = MsgPack<T, false>;

impl<T, const COMPACT: bool> MsgPack<T, COMPACT> {
/// Consumes the `MsgPack` wrapper and returns the wrapped item.
///
Expand All @@ -175,7 +162,7 @@ impl<T, const COMPACT: bool> MsgPack<T, COMPACT> {
/// ```rust
/// # use rocket::serde::msgpack::MsgPack;
/// let string = "Hello".to_string();
/// let my_msgpack = MsgPack(string);
/// let my_msgpack: MsgPack<_> = MsgPack(string);
/// assert_eq!(my_msgpack.into_inner(), "Hello".to_string());
/// ```
#[inline(always)]
Expand Down Expand Up @@ -246,7 +233,9 @@ impl<'r, T: Serialize, const COMPACT: bool> Responder<'r, 'static> for MsgPack<T
}

#[crate::async_trait]
impl<'v, T: Deserialize<'v> + Send, const COMPACT: bool> form::FromFormField<'v> for MsgPack<T, COMPACT> {
impl<'v, T, const COMPACT: bool> form::FromFormField<'v> for MsgPack<T, COMPACT>
where T: Deserialize<'v> + Send
{
// TODO: To implement `from_value`, we need to the raw string so we can
// decode it into bytes as opposed to a string as it won't be UTF-8.

Expand Down Expand Up @@ -334,7 +323,7 @@ pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T, Error>
///
/// The compact representation represents structs as arrays.
///
/// **_Always_ use [`MsgPack`] to serialize MessagePack response data.**
/// **_Always_ use [`Compact`] to serialize compact MessagePack response data.**
///
/// # Example
///
Expand Down
26 changes: 21 additions & 5 deletions core/lib/tests/msgpack_encoding.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#![cfg(feature = "msgpack")]

use rocket::{Rocket, Build};
use rocket::serde::msgpack;
use rocket::serde::msgpack::{MsgPack, Compact};
use rocket::local::blocking::Client;

#[derive(serde::Serialize, serde::Deserialize, PartialEq, Eq)]
Expand All @@ -20,15 +20,15 @@ enum Gender {
}

#[rocket::post("/age_named", data = "<person>")]
fn named(person: msgpack::MsgPack<Person>) -> msgpack::Named<Person> {
fn named(person: MsgPack<Person>) -> MsgPack<Person> {
let person = Person { age: person.age + 1, ..person.into_inner() };
msgpack::MsgPack(person)
MsgPack(person)
}

#[rocket::post("/age_compact", data = "<person>")]
fn compact(person: msgpack::MsgPack<Person>) -> msgpack::Compact<Person> {
fn compact(person: MsgPack<Person>) -> Compact<Person> {
let person = Person { age: person.age + 1, ..person.into_inner() };
msgpack::MsgPack(person)
MsgPack(person)
}

fn rocket() -> Rocket<Build> {
Expand Down Expand Up @@ -70,6 +70,14 @@ fn check_named_roundtrip() {
assert_eq!(rmp::decode::read_map_len(&mut bytes).unwrap(), 1);
assert_eq!(&read_string(&mut bytes), "gender");
assert_eq!(&read_string(&mut bytes), "NonBinary");

let response_from_compact = client
.post("/age_named")
.body(rmp_serde::to_vec(&person).unwrap())
.dispatch()
.into_bytes()
.unwrap();
assert_eq!(response, response_from_compact);
}

#[test]
Expand All @@ -94,4 +102,12 @@ fn check_compact_roundtrip() {
// `[ "Female" ]`.
assert_eq!(rmp::decode::read_array_len(&mut bytes).unwrap(), 1);
assert_eq!(&read_string(&mut bytes), "Female");

let response_from_named = client
.post("/age_compact")
.body(rmp_serde::to_vec_named(&person).unwrap())
.dispatch()
.into_bytes()
.unwrap();
assert_eq!(response, response_from_named);
}

0 comments on commit 02ce87a

Please sign in to comment.