Skip to main content
The bomboni_macros crate provides a collection of convenient macros for working with standard library collections, regular expressions, and other common patterns in Rust.

Regular Expression Macros

regex!

Creates a static regex::Regex instance from a string literal. The regex is compiled once and cached using OnceLock.
use bomboni_macros::regex;

let re = regex!(r"\d{4}-\d{2}-\d{2}");
assert!(re.is_match("2021-08-01"));

// The regex is only compiled once, even if called multiple times
for text in ["2021-01-01", "2022-12-31"] {
    if regex!(r"\d{4}-\d{2}-\d{2}").is_match(text) {
        println!("Valid date: {}", text);
    }
}
Note: This macro creates a static instance, so the regex pattern must be a string literal known at compile time.

Collection Macros

count_repeating!

Counts the number of times a pattern is repeated. Useful for determining the size of a collection at compile time.
use bomboni_macros::count_repeating;

let count = count_repeating!(1, 1, 2, 3, 5);
assert_eq!(count, 5);

let count = count_repeating!("a", "b", "c");
assert_eq!(count, 3);

HashMap Macros

hash_map!

Creates a new HashMap instance with the given key-value pairs or capacity.
use bomboni_macros::hash_map;
use std::collections::HashMap;

// Create an empty HashMap
let map: HashMap<i32, &str> = hash_map!();

// Create a HashMap with capacity
let map: HashMap<i32, String> = hash_map!(100);

// Create a HashMap with key-value pairs
let map = hash_map! {
    1 => "first",
    2 => "second",
    3 => "third",
};
assert_eq!(map.get(&1), Some(&"first"));
assert_eq!(map.get(&2), Some(&"second"));
assert_eq!(map.len(), 3);

hash_map_into!

Creates a new HashMap and converts keys and values using .into().
use bomboni_macros::hash_map_into;
use std::collections::HashMap;

let map: HashMap<i32, String> = hash_map_into! {
    1 => "first",
    2 => "second",
};
assert_eq!(map.get(&1), Some(&"first".to_string()));
assert_eq!(map.get(&2), Some(&"second".to_string()));

BTreeMap Macros

btree_map!

Creates a new BTreeMap instance with the given key-value pairs.
use bomboni_macros::btree_map;
use std::collections::BTreeMap;

// Create an empty BTreeMap
let map: BTreeMap<i32, &str> = btree_map!();

// Create a BTreeMap with key-value pairs
let map = btree_map! {
    1 => "first",
    2 => "second",
    3 => "third",
};
assert_eq!(map.get(&1), Some(&"first"));
assert_eq!(map.get(&2), Some(&"second"));

// Keys are automatically sorted
let keys: Vec<_> = map.keys().copied().collect();
assert_eq!(keys, vec![1, 2, 3]);

btree_map_into!

Creates a new BTreeMap and converts keys and values using .into().
use bomboni_macros::btree_map_into;
use std::collections::BTreeMap;

let map: BTreeMap<i32, String> = btree_map_into! {
    1 => "first",
    2 => "second",
};
assert_eq!(map.get(&1), Some(&"first".to_string()));

HashSet Macros

hash_set!

Creates a new HashSet and inserts the given values.
use bomboni_macros::hash_set;
use std::collections::HashSet;

// Create an empty HashSet
let set: HashSet<i32> = hash_set!();

// Create a HashSet with values
let set = hash_set![1, 2, 3, 4, 5];
assert!(set.contains(&1));
assert!(set.contains(&3));
assert_eq!(set.len(), 5);

// Duplicate values are automatically removed
let set = hash_set![1, 2, 2, 3, 3, 3];
assert_eq!(set.len(), 3);

hash_set_into!

Creates a new HashSet and converts values using .into().
use bomboni_macros::hash_set_into;
use std::collections::HashSet;

let set: HashSet<String> = hash_set_into!["a", "b", "c"];
assert!(set.contains("a"));

BTreeSet Macros

btree_set!

Creates a new BTreeSet and inserts the given values.
use bomboni_macros::btree_set;
use std::collections::BTreeSet;

// Create an empty BTreeSet
let set: BTreeSet<i32> = btree_set!();

// Create a BTreeSet with values
let set = btree_set![3, 1, 4, 1, 5, 9, 2, 6];
assert!(set.contains(&1));
assert!(set.contains(&5));

// Values are automatically sorted and deduplicated
let values: Vec<_> = set.iter().copied().collect();
assert_eq!(values, vec![1, 2, 3, 4, 5, 6, 9]);

btree_set_into!

Creates a new BTreeSet and converts values using .into().
use bomboni_macros::btree_set_into;
use std::collections::BTreeSet;

let set: BTreeSet<String> = btree_set_into!["zebra", "apple", "banana"];

// Values are sorted
let values: Vec<_> = set.iter().map(|s| s.as_str()).collect();
assert_eq!(values, vec!["apple", "banana", "zebra"]);

VecDeque Macros

vec_deque!

Creates a new VecDeque instance with the given values.
use bomboni_macros::vec_deque;
use std::collections::VecDeque;

// Create an empty VecDeque
let deque: VecDeque<i32> = vec_deque!();

// Create a VecDeque with values
let deque = vec_deque![1, 2, 3, 4, 5];
assert_eq!(deque, VecDeque::from(vec![1, 2, 3, 4, 5]));

// Use with repeated elements
let deque = vec_deque![0; 5];
assert_eq!(deque.len(), 5);

vec_deque_into!

Creates a new VecDeque and converts values using .into().
use bomboni_macros::vec_deque_into;
use std::collections::VecDeque;

let deque: VecDeque<String> = vec_deque_into!["first", "second", "third"];
assert_eq!(deque.len(), 3);

Complete Examples

Building Configuration Maps

use bomboni_macros::{hash_map, btree_map};

// Application configuration
let config = hash_map! {
    "host" => "localhost",
    "port" => "8080",
    "debug" => "true",
};

// Sorted configuration for consistent ordering
let sorted_config = btree_map! {
    "api_key" => "secret123",
    "database_url" => "postgres://localhost/db",
    "max_connections" => "10",
};

Working with Sets

use bomboni_macros::{hash_set, btree_set};

// Quick set creation for membership testing
let allowed_methods = hash_set!["GET", "POST", "PUT", "DELETE"];
assert!(allowed_methods.contains(&"GET"));

// Sorted set for consistent iteration
let supported_formats = btree_set!["json", "xml", "csv", "yaml"];
for format in &supported_formats {
    println!("Supported format: {}", format);
}

Pattern Matching with Regex

use bomboni_macros::regex;

fn validate_email(email: &str) -> bool {
    regex!(r"^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$")
        .is_match(email)
}

fn extract_numbers(text: &str) -> Vec<&str> {
    regex!(r"\d+")
        .find_iter(text)
        .map(|m| m.as_str())
        .collect()
}

assert!(validate_email("[email protected]"));
assert_eq!(extract_numbers("There are 42 apples and 7 oranges"), vec!["42", "7"]);

Type Conversion with _into! Variants

use bomboni_macros::{hash_map_into, hash_set_into};
use std::collections::{HashMap, HashSet};

// Automatically convert string literals to String
let settings: HashMap<String, String> = hash_map_into! {
    "theme" => "dark",
    "language" => "en",
};

let tags: HashSet<String> = hash_set_into!["rust", "programming", "tutorial"];

Macro Comparison

MacroPurposeConversion
hash_map!Create HashMapNo conversion
hash_map_into!Create HashMapCalls .into()
btree_map!Create BTreeMapNo conversion
btree_map_into!Create BTreeMapCalls .into()
hash_set!Create HashSetNo conversion
hash_set_into!Create HashSetCalls .into()
btree_set!Create BTreeSetNo conversion
btree_set_into!Create BTreeSetCalls .into()
vec_deque!Create VecDequeNo conversion
vec_deque_into!Create VecDequeCalls .into()
The _into! variants are useful when you need to convert values to their target types, such as converting &str to String.

Build docs developers (and LLMs) love