map_macro/lib.rs
1#![doc = include_str!("../README.md")]
2//!
3//! ## Explicitly Typed Macros
4//!
5//! As shown in the example above, the compiler uses type inference to infer the
6//! correct type for the created map.
7//! Unfortunately, type inference alone sometimes isn't enough.
8//! For example, it can't detect [trait objects][trait objects].
9//! This will not work, because the compiler is unable to figure out the right type:
10//!
11//! ```compile_fail
12//! use std::collections::HashMap;
13//! use std::fmt::Debug;
14//!
15//! use map_macro::hash_map;
16//!
17//! let hello: HashMap<&str, &dyn Debug> = hash_map! {
18//! "en" => &"Hello",
19//! "de" => &"Hallo",
20//! "fr" => &"Bonjour",
21//! "es" => &"Hola",
22//! "cat" => &"Hola",
23//! "🌍" => "👋",
24//! };
25//! ```
26//!
27//! The `map_e!` macro enables you to use trait objects as values through
28//! [type coercion][type coercion], making the example above compile successfully:
29//!
30//! ```rust
31//! use std::collections::HashMap;
32//! use std::fmt::Debug;
33//!
34//! use map_macro::hash_map_e;
35//!
36//! let hello: HashMap<&str, &dyn Debug> = hash_map_e! {
37//! "en" => &"Hello",
38//! "de" => &"Hallo",
39//! "fr" => &"Bonjour",
40//! "es" => &"Hola",
41//! "cat" => &"Hola",
42//! "🌍" => &"👋",
43//! };
44//! ```
45//!
46//! The macro above uses `as`—Rust's [casting operator]—to cast the
47//! provided keys and values to the right type.
48//! It pretty much desugars to:
49//!
50//! ```
51//! use std::collections::HashMap;
52//! use std::fmt::Debug;
53//!
54//! use map_macro::hash_map;
55//!
56//! let hello: HashMap<&str, &dyn Debug> = hash_map! {
57//! "en" as _ => &"Hello" as _,
58//! "de" as _ => &"Hallo" as _,
59//! "fr" as _ => &"Bonjour" as _,
60//! "es" as _ => &"Hola" as _,
61//! "cat" as _ => &"Hola" as _,
62//! "🌍" as _ => &"👋" as _,
63//! };
64//! ```
65//!
66//! This means that all kinds of casts and coercions are supported, including
67//! non-capturing closures to function pointer casts:
68//!
69//! ```rust
70//! use std::collections::HashMap;
71//! use std::fmt::Debug;
72//!
73//! use map_macro::hash_map_e;
74//!
75//! let how_are_you: HashMap<&str, fn() -> &'static str> = hash_map_e! {
76//! "en" => || "How are you?",
77//! "de" => || "Wie geht's dir?",
78//! "fr" => || "Comment vas-tu?",
79//! "es" => || "¿Cómo estás?",
80//! "cat" => || "Com estàs?",
81//! };
82//! ```
83//!
84//! Or casting to convert enums to `u8`:
85//!
86//! ```rust
87//! use std::collections::HashMap;
88//! use std::fmt::Debug;
89//!
90//! use map_macro::hash_map_e;
91//!
92//! enum SupportedLocales {
93//! En,
94//! De,
95//! Fr,
96//! Es,
97//! Cat,
98//! }
99//!
100//! // using enum to integer cast for the keys here
101//! let welcome: HashMap<u8, &str> = hash_map_e! {
102//! SupportedLocales::En => "Welcome",
103//! SupportedLocales::De => "Willkommen",
104//! SupportedLocales::Fr => "Bienvenue",
105//! SupportedLocales::Es => "Bienvenido",
106//! SupportedLocales::Cat => "Benvingut",
107//! };
108//!
109//! assert_eq!(welcome[&0], "Welcome");
110//! assert_eq!(welcome[&1], "Willkommen");
111//! assert_eq!(welcome[&2], "Bienvenue");
112//! assert_eq!(welcome[&3], "Bienvenido");
113//! assert_eq!(welcome[&4], "Benvingut");
114//! ```
115//!
116//! Note that you need to give an explicit type to the binding when you use
117//! `hash_map_e!`, because it relies on knowing what type it should coerce the
118//! values to.
119//!
120//! The explicitly typed versions of the macros are indicated by an `_e` suffix.
121//!
122//! [trait objects]: https://doc.rust-lang.org/reference/types/trait-object.html
123//! [type coercion]: https://doc.rust-lang.org/reference/type-coercions.html
124//! [casting operator]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
125//!
126
127#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
128#![no_std]
129
130#[cfg(feature = "std")]
131extern crate std;
132
133#[cfg(feature = "hashbrown")]
134pub mod hashbrown;
135
136#[cfg(feature = "std")]
137mod _std;