Expand description

map-macro

Build Status Codecov Latest Version Downloads Docs License: MIT

Declarative map! and set! macros.

The map! macro allows for statically initializing a std::collections::HashMap. The same goes for the set! macro only for std::collections::HashSet. The macros are equivalent to the vec! macro offered by the rust standard library for initializing Vec instances.

This crate has zero dependencies.

Usage

Maps

Some languages provide a neat way for creating non-empty maps/dictionaries. For example, in python you can create a non-empty map by running the following code:

hello = {
  "en": "Hello",
  "de": "Hallo",
  "fr": "Bonjour",
  "es": "Hola",
}

In rust, creating a non-empty map (rust has a built-in type in the standard library for creating hash maps std::collections::HashMap) is not as straight-forward:

use std::collections::HashMap;

let mut hello = HashMap::new();

hello.insert("en", "Hello");
hello.insert("de", "Hallo");
hello.insert("fr", "Bonjour");
hello.insert("es", "Hola");

More less-readable boilerplate code is needed in rust to create a non-empty map. Even worse, hello must be declared as mutable, even if we do not want it to be mutable after we have added our four entries. The map-macro crate offers a better way of declaring non-empty maps, with the map! macro. Creating the same hello map from the example above can be simplified to:

use map_macro::map;

let hello = map! {
  "en" => "Hello",
  "de" => "Hallo",
  "fr" => "Bonjour",
  "es" => "Hola",
};

That is it. Looks nearly as neat as the python version with the added benefit that hello is not mutable after we have created it.

The map! macro is powerful enough to create maps from non-static keys and values as well, you are not limited to literals. You can create a map like this:

use map_macro::map;

fn hello_in_french() -> &'static str {
  "Bonjour"
}

fn spanish_language_code() -> &'static str {
  "es"
}

let hello = map! {
  "en" => "Hello",
  "de" => "Hallo",
  "fr" => hello_in_french(),
  spanish_language_code() => "Hola",
};

Empty maps can be created as well, but must provide type hints for the compiler:

use std::collections::HashMap;
use map_macro::map;

let hello: HashMap<&str, &str> = map! {};

assert_eq!(hello.len(), 0);

Rust’s standard library provides a similar macro for creating vectors, vec!. map-macro offers the equivalent macros for creating maps and sets.

Sets

Rust has the same cumbersome creation process for creating sets (in rust sets are provided by the standard library, too, via the std::collections::HashSet struct).

In python you can create a set like this:

x = set([1, 2, 3])

Not as neat as a map, but still quite concise. Dart even comes with syntactic sugar for creating a set:

final x = {1, 2, 3};

In rust, you would have to write:

use std::collections::HashSet;

let mut x = HashSet::new();

x.insert(1);
x.insert(2);
x.insert(3);

The set! macro provided by the map-macro crate lets you write the same code as:

use map_macro::set;

let x = set! { 1, 2, 3 };

Again, nearly as neat as Dart!

The set! macro is as powerful as the map! macro:

use map_macro::set;

fn one() -> i32 {
  1
}

let x = set! { one(), 2, 3 };
use std::collections::HashSet;
use map_macro::set;

let x: HashSet<i32> = set! {};

assert_eq!(x.len(), 0);

Macros

Macro for creating a map.

Macro for creating a set.