Skip to content

Commit

Permalink
btree based sets and maps
Browse files Browse the repository at this point in the history
  • Loading branch information
jofas committed Aug 18, 2022
1 parent 4b772d6 commit f1f8a99
Show file tree
Hide file tree
Showing 4 changed files with 165 additions and 30 deletions.
38 changes: 37 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,17 @@
[![Docs](https://img.shields.io/badge/docs-latest-blue.svg)](https://docs.rs/map-macro/latest/map_macro)
[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)

Declarative `map!`, `set!` and `vec_no_clone!` macros.
Declarative `map!`, `set!`, `btree_map!`, `btree_set!` and
`vec_no_clone!` macros.

The `map!` macro allows for statically initializing a
`std::collections::HashMap`.
The same goes for the `set!` macro only for
`std::collections::HashSet`.
Both macros have an equivalent version using a b-tree data structure
rather than a hashtable-based implementation, `btree_map!` and
`btree_set!` for statically initializing `std::collections::BTreeMap`
and `std::collections::BTreeSet`, respectively.
The macros are equivalent to the `vec!` macro from the rust standard
library.

Expand Down Expand Up @@ -188,6 +193,37 @@ assert_eq!(x.len(), 0);
```


## B-tree based maps and sets

Besides hashtable-based maps and sets, rust's standard library offers
maps and sets based on the b-tree data structure
(`std::collections::BTreeMap` and `std::collections::BTreeSet).
They offer similar functionality to their hashtable-based
counterparts.
`map-macro` offers the `btree_map!` and `btree_set!` macros to
statically initialize the b-tree-based maps and sets.
They work exactly like the `map!` and `set!` macros:

```rust
use map_macro::{btree_map, btree_set};

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

assert_eq!(hello["en"], "Hello");

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

assert!(x.contains(&1));

assert!(!x.contains(&4))
```


## Vectors without cloning

When using the `vec![some_value; count]` syntax, the type of
Expand Down
32 changes: 4 additions & 28 deletions TODO.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,9 @@
# TODO

* [x] crate documentation

* [x] exposed artefacts documentation

* [x] build action

* [x] badges

* [x] clippy action

* [x] publish `v0.2.1`

* [x] `vec_no_clone` macro

* [x] `vec_no_clone` function

* [x] example with `Rc`

* [x] tests

* [x] toc for toplevel documentation (with actions)

* [x] documentation

* [x] publish `v0.2.2`

* [x] `vec_no_clone` fallback to `vec`

* [ ] `btree_map`
* [x] `btree_map`

* [x] `btree_set`

* [ ] `btree_set`
* [ ] publish `v0.2.4`
67 changes: 67 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,41 @@ macro_rules! map {
};
}

/// Macro for creating a [map](std::collections::BTreeMap) based on
/// a b-tree data structure.
///
/// Works just like the [map!] macro.
/// Set this [crate's](crate) documentation for more examples on how
/// to use this macro.
///
/// **Example:**
///
/// ```rust
/// use map_macro::btree_map;
///
/// let goodbye = btree_map! {
/// "en" => "Goodbye",
/// "de" => "Auf Wiedersehen",
/// "fr" => "Au revoir",
/// "es" => "Adios",
/// };
/// ```
///
#[macro_export]
macro_rules! btree_map {
{$($k: expr => $v: expr),* $(,)?} => {
{
let mut map = std::collections::BTreeMap::new();

$(
map.insert($k, $v);
)*

map
}
};
}

/// Macro for creating a [set](std::collections::HashSet).
///
/// Equivalent to the [vec!] macro for [vectors](std::vec::Vec).
Expand Down Expand Up @@ -79,6 +114,38 @@ macro_rules! set {
};
}

/// Macro for creating a [set](std::collections::BTreeSet) based on
/// a b-tree data structure.
///
/// Works just like the [set!] macro.
/// Set this [crate's](crate) documentation for more examples on how
/// to use this macro.
///
/// **Example:**
///
/// ```rust
/// use map_macro::btree_set;
///
/// let x = btree_set! { 1, 2, 3, 3, 4 };
///
/// assert_eq!(x.len(), 4);
/// ```
///
#[macro_export]
macro_rules! btree_set {
{$($v: expr),* $(,)?} => {
{
let mut set = std::collections::BTreeSet::new();

$(
set.insert($v);
)*

set
}
};
}

/// More flexible version of the [vec](std::vec) macro from the
/// standard library.
///
Expand Down
58 changes: 57 additions & 1 deletion tests/tests.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use map_macro::{map, set, vec_no_clone};
use map_macro::{btree_map, btree_set, map, set, vec_no_clone};

#[test]
fn map1() {
Expand Down Expand Up @@ -56,6 +56,62 @@ fn set2() {
assert!(!s.contains(&4));
}

#[test]
fn btree_map1() {
let m = btree_map! {
"en" => "Hello",
"de" => "Hallo",
"fr" => "Bonjour",
"es" => "Hola",
};

assert_eq!(m["en"], "Hello");
assert_eq!(m["de"], "Hallo");
assert_eq!(m["fr"], "Bonjour");
assert_eq!(m["es"], "Hola");
}

#[test]
fn btree_map2() {
let m = btree_map! {
0 => "a",
1 => "b",
2 => "c",
};

assert_eq!(m[&0], "a");
assert_eq!(m[&1], "b");
assert_eq!(m[&2], "c");
}

#[test]
fn btree_set1() {
let s = btree_set! { "a", "b", "c", "d" };

assert_eq!(s.len(), 4);

assert!(s.contains("a"));
assert!(s.contains("b"));
assert!(s.contains("c"));
assert!(s.contains("d"));

assert!(!s.contains("e"));
}

#[test]
fn btree_set2() {
let s = btree_set! { 0, 1, 2, 3, 0 };

assert_eq!(s.len(), 4);

assert!(s.contains(&0));
assert!(s.contains(&1));
assert!(s.contains(&2));
assert!(s.contains(&3));

assert!(!s.contains(&4));
}

#[derive(PartialEq, Debug)]
struct UnclonableWrapper(i8);

Expand Down

0 comments on commit f1f8a99

Please sign in to comment.