Expose 'msgpack::from_slice', 'json::from_value'.

This commit is contained in:
Sergio Benitez 2021-06-02 16:59:42 -07:00
parent 74299a9719
commit f8efa64ae2
2 changed files with 187 additions and 39 deletions

View File

@ -35,9 +35,6 @@ use crate::form::prelude as form;
use serde::{Serialize, Deserialize}; use serde::{Serialize, Deserialize};
#[doc(inline)]
pub use serde_json::{from_str, from_slice};
#[doc(hidden)] #[doc(hidden)]
pub use serde_json; pub use serde_json;
@ -252,42 +249,6 @@ impl<'v, T: Deserialize<'v> + Send> form::FromFormField<'v> for Json<T> {
} }
} }
/// An arbitrary JSON value.
///
/// This structure wraps `serde`'s [`Value`] type. Importantly, unlike `Value`,
/// this type implements [`Responder`], allowing a value of this type to be
/// returned directly from a handler.
///
/// [`Value`]: serde_json::value
/// [`Responder`]: crate::response::Responder
///
/// # `Responder`
///
/// The `Responder` implementation for `Value` serializes the represented
/// value into a JSON string and sets the string as the body of a fixed-sized
/// response with a `Content-Type` of `application/json`.
///
/// # Usage
///
/// A value of this type is constructed via the [`json!`](json) macro. The macro
/// and this type are typically used to construct JSON values in an ad-hoc
/// fashion during request handling. This looks something like:
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::serde::json::{json, Value};
///
/// #[get("/json")]
/// fn get_json() -> Value {
/// json!({
/// "id": 83,
/// "values": [1, 2, 3, 4]
/// })
/// }
/// ```
#[doc(inline)]
pub use serde_json::Value;
/// Serializes the value into JSON. Returns a response with Content-Type JSON /// Serializes the value into JSON. Returns a response with Content-Type JSON
/// and a fixed-size body with the serialized value. /// and a fixed-size body with the serialized value.
impl<'r> Responder<'r, 'static> for Value { impl<'r> Responder<'r, 'static> for Value {
@ -380,3 +341,153 @@ crate::export! {
($($json:tt)+) => ($crate::serde::json::serde_json::json!($($json)*)); ($($json:tt)+) => ($crate::serde::json::serde_json::json!($($json)*));
} }
} }
/// An arbitrary JSON value as returned by [`json!`].
///
/// # `Responder`
///
/// `Value` is a `Responder` that serializes the represented value into a JSON
/// string and sets the string as the body of a fixed-sized response with a
/// `Content-Type` of `application/json`.
///
/// # Usage
///
/// A value of this type is returned by [`json!`]. The macro and this type are
/// typically used to construct JSON values in an ad-hoc fashion during request
/// handling. This looks something like:
///
/// ```rust
/// # #[macro_use] extern crate rocket;
/// use rocket::serde::json::{json, Value};
///
/// #[get("/json")]
/// fn get_json() -> Value {
/// json!({
/// "id": 83,
/// "values": [1, 2, 3, 4]
/// })
/// }
/// ```
#[doc(inline)]
pub use serde_json::Value;
/// Deserialize an instance of type `T` from bytes of JSON text.
///
/// # Example
///
/// ```
/// use rocket::serde::{Deserialize, json};
///
/// #[derive(Debug, PartialEq, Deserialize)]
/// #[serde(crate = "rocket::serde")]
/// struct Data<'r> {
/// framework: &'r str,
/// stars: usize,
/// }
///
/// let bytes = br#"
/// {
/// "framework": "Rocket",
/// "stars": 5
/// }
/// "#;
///
/// let data: Data = json::from_slice(bytes).unwrap();
/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
/// ```
///
/// # Errors
///
/// This conversion can fail if the structure of the input does not match the
/// structure expected by `T`, for example if `T` is a struct type but the input
/// contains something other than a JSON map. It can also fail if the structure
/// is correct but `T`'s implementation of `Deserialize` decides that something
/// is wrong with the data, for example required struct fields are missing from
/// the JSON map or some number is too big to fit in the expected primitive
/// type.
#[inline(always)]
pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T, serde_json::error::Error>
where T: Deserialize<'a>,
{
serde_json::from_slice(v)
}
/// Deserialize an instance of type `T` from a string of JSON text.
///
/// # Example
///
/// ```
/// use rocket::serde::{Deserialize, json};
///
/// #[derive(Debug, PartialEq, Deserialize)]
/// #[serde(crate = "rocket::serde")]
/// struct Data<'r> {
/// framework: &'r str,
/// stars: usize,
/// }
///
/// let string = r#"
/// {
/// "framework": "Rocket",
/// "stars": 5
/// }
/// "#;
///
/// let data: Data = json::from_str(string).unwrap();
/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
/// ```
///
/// # Errors
///
/// This conversion can fail if the structure of the input does not match the
/// structure expected by `T`, for example if `T` is a struct type but the input
/// contains something other than a JSON map. It can also fail if the structure
/// is correct but `T`'s implementation of `Deserialize` decides that something
/// is wrong with the data, for example required struct fields are missing from
/// the JSON map or some number is too big to fit in the expected primitive
/// type.
#[inline(always)]
pub fn from_str<'a, T>(v: &'a str) -> Result<T, serde_json::error::Error>
where T: Deserialize<'a>,
{
serde_json::from_str(v)
}
/// Interpret a [`Value`] as an instance of type `T`.
///
/// # Example
///
/// ```
/// use rocket::serde::{Deserialize, json};
///
/// #[derive(Debug, PartialEq, Deserialize)]
/// #[serde(crate = "rocket::serde")]
/// struct Data {
/// framework: String ,
/// stars: usize,
/// }
///
/// let value = json::json!({
/// "framework": "Rocket",
/// "stars": 5
/// });
///
/// let data: Data = json::from_value(value).unwrap();
/// assert_eq!(data, Data { framework: "Rocket".into(), stars: 5, });
/// ```
///
/// # Errors
///
/// This conversion can fail if the structure of the input does not match the
/// structure expected by `T`, for example if `T` is a struct type but the input
/// contains something other than a JSON map. It can also fail if the structure
/// is correct but `T`'s implementation of `Deserialize` decides that something
/// is wrong with the data, for example required struct fields are missing from
/// the JSON map or some number is too big to fit in the expected primitive
/// type.
#[inline(always)]
pub fn from_value<T>(v: Value) -> Result<T, serde_json::error::Error>
where T: crate::serde::DeserializeOwned
{
serde_json::from_value(v)
}

View File

@ -231,3 +231,40 @@ impl<T> DerefMut for MsgPack<T> {
&mut self.0 &mut self.0
} }
} }
/// Deserialize an instance of type `T` from MessagePack encoded bytes.
///
/// Deserialization is performed in a zero-copy manner whenever possible.
///
/// # Example
///
/// ```
/// use rocket::serde::{Deserialize, msgpack};
///
/// #[derive(Debug, PartialEq, Deserialize)]
/// #[serde(crate = "rocket::serde")]
/// struct Data<'r> {
/// framework: &'r str,
/// stars: usize,
/// }
///
/// let bytes = &[
/// 130, 169, 102, 114, 97, 109, 101, 119, 111, 114, 107, 166, 82, 111,
/// 99, 107, 101, 116, 165, 115, 116, 97, 114, 115, 5
/// ];
///
/// let data: Data = msgpack::from_slice(bytes).unwrap();
/// assert_eq!(data, Data { framework: "Rocket", stars: 5, });
/// ```
///
/// # Errors
///
/// Deserialization fails if `v` does not represent a valid MessagePack encoding
/// of any instance of `T` or if `T`'s `Deserialize` implementation fails
/// otherwise.
#[inline(always)]
pub fn from_slice<'a, T>(v: &'a [u8]) -> Result<T, Error>
where T: Deserialize<'a>,
{
rmp_serde::from_read_ref(v)
}