diff --git a/core/lib/src/serde/msgpack.rs b/core/lib/src/serde/msgpack.rs index 85756c79..843890f1 100644 --- a/core/lib/src/serde/msgpack.rs +++ b/core/lib/src/serde/msgpack.rs @@ -43,12 +43,25 @@ pub use rmp_serde::decode::Error; /// /// ## Sending MessagePack /// -/// To respond with serialized MessagePack data, return either [`Named`] or +/// To respond with serialized MessagePack data, return either [`MsgPack`] or /// [`Compact`] from your handler. `T` must implement [`serde::Serialize`]. /// -/// Currently, returning `MsgPack` is equivalent to returning `Compact`, -/// 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/")] +/// fn user(id: usize) -> MsgPack { +/// let user_from_id = User::from(id); +/// /* ... */ +/// MsgPack(user_from_id) +/// } +/// ``` +/// +/// The differences between [`MsgPack`] and [`Compact`] are documented on +/// [`Compact`]. In most cases, [`MsgPack`] is preferable, although compact +/// was the default prior to Rocket version 0.6. /// /// ## Receiving MessagePack /// @@ -113,7 +126,7 @@ pub use rmp_serde::decode::Error; /// msgpack = 5242880 /// ``` #[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] -pub struct MsgPack(pub T); +pub struct MsgPack(pub T); /// Serializes responses in a compact MesagePack format, where structs are /// serialized as arrays of their field values. @@ -141,32 +154,6 @@ pub struct MsgPack(pub T); /// NOT prevent named requests from being accepted. pub type Compact = MsgPack; -/// 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` 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/")] -/// fn user(id: usize) -> msgpack::Named { -/// let user_from_id = User::from(id); -/// /* ... */ -/// msgpack::MsgPack(user_from_id) -/// } -/// ``` -/// -/// Prefer using [`MsgPack`] for request guards, as the named/compact -/// distinction is not relevant for request data - the correct option is -/// implemented automatically. Using [`Named`] as a request guard will -/// NOT prevent compact requests from being accepted. -pub type Named = MsgPack; - impl MsgPack { /// Consumes the `MsgPack` wrapper and returns the wrapped item. /// @@ -175,7 +162,7 @@ impl MsgPack { /// ```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)] @@ -246,7 +233,9 @@ impl<'r, T: Serialize, const COMPACT: bool> Responder<'r, 'static> for MsgPack + Send, const COMPACT: bool> form::FromFormField<'v> for MsgPack { +impl<'v, T, const COMPACT: bool> form::FromFormField<'v> for MsgPack + 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. @@ -334,7 +323,7 @@ pub fn from_slice<'a, T>(v: &'a [u8]) -> Result /// /// 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 /// diff --git a/core/lib/tests/msgpack_encoding.rs b/core/lib/tests/msgpack_encoding.rs index 575da5fa..eeb3c7a4 100644 --- a/core/lib/tests/msgpack_encoding.rs +++ b/core/lib/tests/msgpack_encoding.rs @@ -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)] @@ -20,15 +20,15 @@ enum Gender { } #[rocket::post("/age_named", data = "")] -fn named(person: msgpack::MsgPack) -> msgpack::Named { +fn named(person: MsgPack) -> MsgPack { let person = Person { age: person.age + 1, ..person.into_inner() }; - msgpack::MsgPack(person) + MsgPack(person) } #[rocket::post("/age_compact", data = "")] -fn compact(person: msgpack::MsgPack) -> msgpack::Compact { +fn compact(person: MsgPack) -> Compact { let person = Person { age: person.age + 1, ..person.into_inner() }; - msgpack::MsgPack(person) + MsgPack(person) } fn rocket() -> Rocket { @@ -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] @@ -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); }