Allow any Serialize type in RHS of map macro.

This commit is contained in:
Sergio Benitez 2016-12-28 21:01:16 -06:00
parent 0a0b64b9b6
commit c61e740572
3 changed files with 31 additions and 14 deletions

View File

@ -14,6 +14,11 @@ use self::serde::{Serialize, Deserialize};
pub use self::serde_json::error::Error as SerdeError; pub use self::serde_json::error::Error as SerdeError;
pub use self::serde_json::value::Value;
#[doc(hidden)]
pub use self::serde_json::to_value;
/// The JSON type, which implements `FromData` and `Responder`. This type allows /// The JSON type, which implements `FromData` and `Responder`. This type allows
/// you to trivially consume and respond with JSON in your Rocket application. /// you to trivially consume and respond with JSON in your Rocket application.
/// ///
@ -117,31 +122,38 @@ impl<T> DerefMut for JSON<T> {
} }
} }
/// A nice little macro to create simple HashMaps. Really convenient for /// A nice little macro to create JSON serializable HashMaps, convenient for
/// returning ad-hoc JSON messages. /// returning ad-hoc JSON messages.
/// ///
/// Keys can be any type that implements `Serialize`. All keys must have the
/// same type, which is usually an `&'static str`. Values can be any type that
/// implements `Serialize` as well, but each value is allowed to be a different
/// type.
///
/// # Examples /// # Examples
/// ///
/// ``` /// ```
/// # #[macro_use] extern crate rocket_contrib; /// # #[macro_use] extern crate rocket_contrib;
/// use std::collections::HashMap;
/// # fn main() { /// # fn main() {
/// let map: HashMap<&str, usize> = map! { /// let map = map! {
/// "status" => 0, /// "message" => "Done!",
/// "count" => 100 /// "success" => true,
/// "count" => 3,
/// }; /// };
/// ///
/// assert_eq!(map.len(), 2); /// assert_eq!(map.len(), 3);
/// assert_eq!(map.get("status"), Some(&0)); /// assert_eq!(map.get("message").and_then(|v| v.as_str()), Some("Done!"));
/// assert_eq!(map.get("count"), Some(&100)); /// assert_eq!(map.get("success").and_then(|v| v.as_bool()), Some(true));
/// assert_eq!(map.get("count").and_then(|v| v.as_u64()), Some(3));
/// # } /// # }
/// ``` /// ```
#[macro_export] #[macro_export]
macro_rules! map { macro_rules! map {
($($key:expr => $value:expr),+) => ({ ($($key:expr => $value:expr),+) => ({
use std::collections::HashMap; use ::std::collections::HashMap;
let mut map = HashMap::new(); use $crate::json::{Value, to_value};
$(map.insert($key, $value);)+ let mut map: HashMap<_, Value> = HashMap::new();
$(map.insert($key, to_value($value));)+
map map
}); });

View File

@ -42,7 +42,8 @@ extern crate lazy_static;
#[cfg_attr(feature = "json", macro_use)] #[cfg_attr(feature = "json", macro_use)]
#[cfg(feature = "json")] #[cfg(feature = "json")]
mod json; #[doc(hidden)]
pub mod json;
#[cfg(feature = "templates")] #[cfg(feature = "templates")]
mod templates; mod templates;
@ -52,6 +53,8 @@ mod uuid;
#[cfg(feature = "json")] #[cfg(feature = "json")]
pub use json::JSON; pub use json::JSON;
#[cfg(feature = "json")]
pub use json::Value;
#[cfg(feature = "json")] #[cfg(feature = "json")]
pub use json::SerdeError; pub use json::SerdeError;

View File

@ -9,13 +9,15 @@ extern crate serde_json;
#[cfg(test)] mod tests; #[cfg(test)] mod tests;
use rocket_contrib::JSON; use rocket_contrib::{JSON, Value};
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::Mutex; use std::sync::Mutex;
// The type to represent the ID of a message. // The type to represent the ID of a message.
type ID = usize; type ID = usize;
type SimpleMap = HashMap<&'static str, &'static str>;
// The type of a `map!` invocation.
type SimpleMap = HashMap<&'static str, Value>;
// We're going to store all of the messages here. No need for a DB. // We're going to store all of the messages here. No need for a DB.
lazy_static! { lazy_static! {