https://github.com/pscheidl/enum-collections
EnumMap for Rust.
https://github.com/pscheidl/enum-collections
collections data-structures enum enum-map enummap rust rust-lang
Last synced: 5 days ago
JSON representation
EnumMap for Rust.
- Host: GitHub
- URL: https://github.com/pscheidl/enum-collections
- Owner: Pscheidl
- License: apache-2.0
- Created: 2022-12-25T18:35:35.000Z (over 2 years ago)
- Default Branch: master
- Last Pushed: 2024-05-16T09:12:57.000Z (about 1 year ago)
- Last Synced: 2024-05-17T08:33:08.318Z (about 1 year ago)
- Topics: collections, data-structures, enum, enum-map, enummap, rust, rust-lang
- Language: Rust
- Homepage:
- Size: 272 KB
- Stars: 5
- Watchers: 2
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# EnumMap for Rust
[](https://github.com/Pscheidl/enum-map/actions/workflows/rust.yml)
[](https://crates.io/crates/enum-collections)
[](https://docs.rs/enum-collections/latest/enum_collections/)[Contribution guide](CONTRIBUTING.md) | [Apache v2 license](LICENSE)
A map of enum variants to values. EnumMap is a fixed-size map, where each variant of the enum is mapped to a value. This implementation of EnumMap uses **safe Rust** only and is a a zero-cost abstraction over an array (**const-sized**), where the index of the array corresponds to the position of the variant in the enum.
Because it is a thin wrapper over an array, it is stack-allocated by default. Simply `std::boxed::Box`ing it will move it to the heap, at the caller's discretion.
- Indexed by enum variants.
- IndexMut by enum variants.
- Debug if the enum is Debug.
- PartialEq if the value is PartialEq. Same for Eq.Debug and Eq are optional features. They are enabled by default.
## Usage
Please refer to the [documentation](https://docs.rs/enum-collections/latest/enum_collections/) for a complete list of features and more in-depth documentation.
```rust
use enum_collections::{EnumMap, Enumerated, em, em_default, em_option};#[derive(Enumerated)]
pub enum Letter {
A,
B,
}// Indexing and mutation
// The SIZE hint is required until [generic_const_expr](https://github.com/rust-lang/rust/issues/76560) are stabilized.
let mut enum_map = EnumMap::::new_default();
assert_eq!(0, enum_map[Letter::A]);
enum_map[Letter::A] = 42;
assert_eq!(42, enum_map[Letter::A]);// Construction using macros
// (Key type, Value type, Key=>Value pairs)
let enum_map = em!(Letter, i32, A=>42, B=>24); // All values set explicitly
assert_eq!(42, enum_map[Letter::A]);
assert_eq!(24, enum_map[Letter::B]);// (Key type, Value type, optional Key=>Value pairs)
let enum_map = em_default!(Letter, i32, A => 42); // Default used for missing values
assert_eq!(42, enum_map[Letter::A]);
assert_eq!(i32::default(), enum_map[Letter::B]);let enum_map = em_default!(Letter, i32,); // All default
assert_eq!(i32::default(), enum_map[Letter::A]);
assert_eq!(i32::default(), enum_map[Letter::B]);// EnumMap of optional values `Option`, value type is automatically wrapped in `Option`.
// (Key type, Value type, optional Key=>Value pairs)
let enum_map = em_option!(Letter, i32, A => 42);
assert_eq!(Some(42), enum_map[Letter::A]);
assert_eq!(None, enum_map[Letter::B]);// Constructor with default values
let enum_map_default = EnumMap::::new_default();
assert_eq!(0, enum_map_default[Letter::A]);
assert_eq!(0, enum_map_default[Letter::B]);// Convenience constructor for optional values
let mut enum_map_option = EnumMap::, { Letter::SIZE }>::new_option();
assert_eq!(None, enum_map_option[Letter::A]);
assert_eq!(None, enum_map_option[Letter::B]);
enum_map_option[Letter::A] = Some(42);
assert_eq!(Some(42), enum_map_option[Letter::A]);// Constructor with custom initialization
#[derive(PartialEq, Eq, Debug)]
struct Custom;
let enum_map = EnumMap::::new(|| Custom);
assert_eq!(Custom, enum_map[Letter::A]);
assert_eq!(Custom, enum_map[Letter::B]);// Custom initialization function with enum variant (key) inspection
let enum_map = EnumMap::::new_inspect(|letter| {
match letter {
Letter::A => 42,
Letter::B => 24,
}
});
assert_eq!(42, enum_map[Letter::A]);
assert_eq!(24, enum_map[Letter::B]);// Debug
#[derive(Enumerated, Debug)]
pub enum LetterDebugDerived {
A,
B,
}
let enum_map_debug =
EnumMap::::new(|| 42);
assert_eq!("{A: 42, B: 42}", format!("{:?}", enum_map_debug));```
Iterate over enum variants
```rust
#[derive(Enumerated, Debug)]
pub enum Letter {
A,
B,
}Letter::VARIANTS
.iter()
.for_each(|letter| println!("{:?}", letter));
```## Features
Portions of functionality are feature-flagged, but enabled by default. This is to allow turning this functionality off when not needed, e.g. `Debug` and `Eq` implementations.
See [docs.rs](https://docs.rs/crate/enum-collections/latest/features) for details.## Benchmarks
Invoke `cargo bench` to run benchmarks. While `EnumMap` operates in pico-seconds, `std::collections::HashMap` in > 10 nanoseconds.
Benchmark results
```
EnumMap get time: [221.09 ps 221.59 ps 222.21 ps]
Found 10 outliers among 100 measurements (10.00%)
5 (5.00%) high mild
5 (5.00%) high severeEnumMap insert time: [230.05 ps 233.38 ps 236.25 ps]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severeEnumMap new: default time: [852.31 ps 853.28 ps 854.37 ps]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) low mild
1 (1.00%) high mildEnumMap new: Option::None
time: [1.7100 ns 1.7110 ns 1.7120 ns]
Found 2 outliers among 100 measurements (2.00%)
1 (1.00%) high mild
1 (1.00%) high severeEnumMap new: provider fn
time: [791.17 ps 792.38 ps 793.65 ps]
Found 7 outliers among 100 measurements (7.00%)
1 (1.00%) low mild
4 (4.00%) high mild
2 (2.00%) high severeEnumMap new: inspecting provider fn
time: [775.03 ps 776.84 ps 778.92 ps]
Found 8 outliers among 100 measurements (8.00%)
4 (4.00%) high mild
4 (4.00%) high severestd::collections::HashMap get
time: [13.433 ns 13.484 ns 13.543 ns]
Found 8 outliers among 100 measurements (8.00%)
3 (3.00%) high mild
5 (5.00%) high severestd::collections::HashMap insert
time: [14.094 ns 14.107 ns 14.121 ns]
Found 4 outliers among 100 measurements (4.00%)
1 (1.00%) high mild
3 (3.00%) high severe```