Crate map_macro

Source
Expand description

§map-macro

Build Status Latest Version Downloads Docs License: MIT

This crate offers declarative macros for initializing collections from the standard library and hashbrown.

This crate has zero dependencies and is #![no_std] if you opt-out of support for the standard library collections.

§Example

use map_macro::hash_map;

let hello = hash_map! {
    "en" => "Hello",
    "de" => "Hallo",
    "fr" => "Bonjour",
    "es" => "Hola",
    "cat" => "Hola",
    "🌍" => "👋",
};

§Explicitly Typed Macros

As shown in the example above, the compiler uses type inference to infer the correct type for the created map. Unfortunately, type inference alone sometimes isn’t enough. For example, it can’t detect trait objects. This will not work, because the compiler is unable to figure out the right type:

use std::collections::HashMap;
use std::fmt::Debug;

use map_macro::hash_map;

let hello: HashMap<&str, &dyn Debug> = hash_map! {
    "en" => &"Hello",
    "de" => &"Hallo",
    "fr" => &"Bonjour",
    "es" => &"Hola",
    "cat" => &"Hola",
    "🌍" => "👋",
};

The map_e! macro enables you to use trait objects as values through type coercion, making the example above compile successfully:

use std::collections::HashMap;
use std::fmt::Debug;

use map_macro::hash_map_e;

let hello: HashMap<&str, &dyn Debug> = hash_map_e! {
    "en" => &"Hello",
    "de" => &"Hallo",
    "fr" => &"Bonjour",
    "es" => &"Hola",
    "cat" => &"Hola",
    "🌍" => &"👋",
};

The macro above uses as—Rust’s casting operator—to cast the provided keys and values to the right type. It pretty much desugars to:

use std::collections::HashMap;
use std::fmt::Debug;

use map_macro::hash_map;

let hello: HashMap<&str, &dyn Debug> = hash_map! {
    "en" as _ => &"Hello" as _,
    "de" as _ => &"Hallo" as _,
    "fr" as _ => &"Bonjour" as _,
    "es" as _ => &"Hola" as _,
    "cat" as _ => &"Hola" as _,
    "🌍" as _ => &"👋" as _,
};

This means that all kinds of casts and coercions are supported, including non-capturing closures to function pointer casts:

use std::collections::HashMap;
use std::fmt::Debug;

use map_macro::hash_map_e;

let how_are_you: HashMap<&str, fn() -> &'static str> = hash_map_e! {
    "en" => || "How are you?",
    "de" => || "Wie geht's dir?",
    "fr" => || "Comment vas-tu?",
    "es" => || "¿Cómo estás?",
    "cat" => || "Com estàs?",
};

Or casting to convert enums to u8:

use std::collections::HashMap;
use std::fmt::Debug;

use map_macro::hash_map_e;

enum SupportedLocales {
    En,
    De,
    Fr,
    Es,
    Cat,
}

// using enum to integer cast for the keys here
let welcome: HashMap<u8, &str> = hash_map_e! {
    SupportedLocales::En => "Welcome",
    SupportedLocales::De => "Willkommen",
    SupportedLocales::Fr => "Bienvenue",
    SupportedLocales::Es => "Bienvenido",
    SupportedLocales::Cat => "Benvingut",
};

assert_eq!(welcome[&0], "Welcome");
assert_eq!(welcome[&1], "Willkommen");
assert_eq!(welcome[&2], "Bienvenue");
assert_eq!(welcome[&3], "Bienvenido");
assert_eq!(welcome[&4], "Benvingut");

Note that you need to give an explicit type to the binding when you use hash_map_e!, because it relies on knowing what type it should coerce the values to.

The explicitly typed versions of the macros are indicated by an _e suffix.

Modules§

hashbrownhashbrown
Macros for initializing hashbrown maps and sets.

Macros§

binary_heapstd
Macro for creating a BinaryHeap.
binary_heap_estd
Explicitly typed equivalent of binary_heap!.
btree_mapstd
Macro for creating a BTreeMap.
btree_map_estd
Explicitly typed equivalent of btree_map!.
btree_setstd
Macro for creating a BTreeSet.
btree_set_estd
Explicitly typed equivalent of btree_set!.
hash_mapstd
Macro for creating a HashMap.
hash_map_estd
Explicitly typed equivalent of hash_map!.
hash_setstd
Macro for creating a HashSet.
hash_set_estd
Explicitly typed equivalent of hash_set!.
linked_liststd
Macro for creating a LinkedList.
linked_list_estd
Explicitly typed equivalent of linked_list!.
vec_dequestd
Macro for creating a VecDeque.
vec_deque_estd
Explicitly typed equivalent of vec_deque!.
vec_no_clonestd
Version of the vec! macro where the value does not have to implement Clone.
vec_no_clone_estd
Explicitly typed equivalent of vec_no_clone!.