halfbrown/
macros.rs

1#![warn(missing_docs)]
2#![warn(unused_results)]
3
4//! Taken from: <https://docs.rs/maplit/1/>
5//! Macros for halfbrown literals.
6//!
7//! ```no_run
8//! #[macro_use] extern crate halfbrown;
9//!
10//! # fn main() {
11//! let map = hashmap!{
12//!     "a" => 1,
13//!     "b" => 2,
14//! };
15//! # }
16//! ```
17//!
18//! The **halfbrown** crate uses `=>` syntax to separate the key and value for the
19//! mapping macros. (It was not possible to use `:` as separator due to syntactic
20//! restrictions in regular `macro_rules!` macros.)
21//!
22//! Note that rust macros are flexible in which brackets you use for the invocation.
23//! You can use them as `hashmap!{}` or `hashmap![]` or `hashmap!()`.
24//!
25//! Generic container macros already exist elsewhere, so those are not provided
26//! here at the moment.
27
28#[macro_export]
29/// Create a **`HashMap`** from a list of key-value pairs
30///
31/// ## Example
32///
33/// ```no_run
34/// #[macro_use] extern crate halfbrown;
35/// # fn main() {
36///
37/// let map = hashmap!{
38///     "a" => 1,
39///     "b" => 2,
40/// };
41/// assert_eq!(map["a"], 1);
42/// assert_eq!(map["b"], 2);
43/// assert_eq!(map.get("c"), None);
44/// # }
45/// ```
46macro_rules! hashmap {
47    (@single $($x:tt)*) => (());
48    (@count $($rest:expr),*) => (<[()]>::len(&[$(hashmap!(@single $rest)),*]));
49
50    ($($key:expr => $value:expr,)+) => { hashmap!($($key => $value),+) };
51    ($($key:expr => $value:expr),*) => {
52        {
53            let _cap = hashmap!(@count $($key),*);
54            #[allow(clippy::let_and_return)]
55            let mut _map: $crate::HashMap<_,_> = $crate::HashMap::with_capacity(_cap);
56            $(
57                #[allow(let_underscore_drop)]
58                let _: Option<_> = _map.insert($key, $value);
59            )*
60            _map
61        }
62    };
63}
64
65/// Identity function. Used as the fallback for conversion.
66#[doc(hidden)]
67pub fn __id<T>(t: T) -> T {
68    t
69}
70
71#[test]
72fn test_hashmap() {
73    use crate::SizedHashMap;
74    let names = hashmap! {
75        1 => "one",
76        2 => "two",
77    };
78    assert_eq!(names.len(), 2);
79    assert_eq!(names[&1], "one");
80    assert_eq!(names[&2], "two");
81    assert_eq!(names.get(&3), None);
82
83    let empty: SizedHashMap<i32, i32> = hashmap! {};
84    assert_eq!(empty.len(), 0);
85
86    let _nested_compiles = hashmap! {
87        1 => hashmap!{0 => 1 + 2,},
88        2 => hashmap!{1 => 1,},
89    };
90}