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}