pub struct EnumTable<K: Enumable, V, const N: usize> { /* private fields */ }Expand description
A table that associates each variant of an enumeration with a value.
EnumTable is a generic struct that uses an enumeration as keys and stores
associated values. It provides efficient constant-time access (O(1))
to the values based on the enumeration variant. This is particularly useful
when you want to map enum variants to specific values without the overhead
of a HashMap.
§Guarantees and Design
The core design principle of EnumTable is that an instance is guaranteed to hold a
value for every variant of the enum K. This guarantee allows for a cleaner API
than general-purpose map structures.
For example, the Self::get method returns &V directly. This is in contrast to
std::collections::HashMap::get, which returns an Option<&V> because a key may or may not be
present. With EnumTable, the presence of all keys (variants) is a type-level
invariant, eliminating the need for unwrap() or other Option handling.
If you need to handle cases where a value might not be present or will be set
later, you can use Option<V> as the value type: EnumTable<K, Option<V>, N>.
The struct provides convenient methods like Self::new_fill_with_none for this pattern.
§Type Parameters
K: The enumeration type that implements theEnumabletrait. This trait ensures that the enum provides a static array of its variants and a count of these variants.V: The type of values to be associated with each enum variant.N: The number of variants in the enum, which should match the length of the static array of variants provided by theEnumabletrait.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Copy, Clone)]
enum Color {
Red,
Green,
Blue,
}
// Create an EnumTable using the new_with_fn method
let table = EnumTable::<Color, &'static str, { Color::COUNT }>::new_with_fn(|color| match color {
Color::Red => "Red",
Color::Green => "Green",
Color::Blue => "Blue",
});
// Access values associated with enum variants
assert_eq!(table.get(&Color::Red), &"Red");
assert_eq!(table.get(&Color::Green), &"Green");
assert_eq!(table.get(&Color::Blue), &"Blue");Implementations§
Source§impl<K: Enumable, V, const N: usize> EnumTable<K, V, N>
impl<K: Enumable, V, const N: usize> EnumTable<K, V, N>
Sourcepub fn keys(&self) -> Iter<'_, K>
pub fn keys(&self) -> Iter<'_, K>
Returns an iterator over references to the keys in the table.
Sourcepub fn values(&self) -> Iter<'_, V>
pub fn values(&self) -> Iter<'_, V>
Returns an iterator over references to the values in the table.
Sourcepub fn values_mut(&mut self) -> IterMut<'_, V>
pub fn values_mut(&mut self) -> IterMut<'_, V>
Returns an iterator over mutable references to the values in the table.
Source§impl<K: Enumable + Eq + Hash, V, const N: usize> EnumTable<K, V, N>
impl<K: Enumable + Eq + Hash, V, const N: usize> EnumTable<K, V, N>
Sourcepub fn into_hash_map(self) -> HashMap<K, V>
pub fn into_hash_map(self) -> HashMap<K, V>
Converts the EnumTable into a HashMap.
This method consumes the EnumTable and creates a new HashMap with the same
key-value pairs. Each enum variant is mapped to its associated value.
§Examples
use enum_table::{EnumTable, Enumable};
use std::collections::HashMap;
#[derive(Enumable, Debug, PartialEq, Eq, Hash, Copy, Clone)]
enum Status {
Active,
Inactive,
Pending,
}
let table = EnumTable::<Status, &str, { Status::COUNT }>::new_with_fn(|status| match status {
Status::Active => "running",
Status::Inactive => "stopped",
Status::Pending => "waiting",
});
let hash_map = table.into_hash_map();
assert_eq!(hash_map.get(&Status::Active), Some(&"running"));
assert_eq!(hash_map.get(&Status::Inactive), Some(&"stopped"));
assert_eq!(hash_map.get(&Status::Pending), Some(&"waiting"));
assert_eq!(hash_map.len(), 3);Sourcepub fn try_from_hash_map(map: HashMap<K, V>) -> Option<EnumTable<K, V, N>>
pub fn try_from_hash_map(map: HashMap<K, V>) -> Option<EnumTable<K, V, N>>
Creates an EnumTable from a HashMap.
Returns None if the HashMap doesn’t contain exactly one entry for each enum variant.
The HashMap must have exactly N entries where N is the number of enum variants.
§Arguments
map- AHashMapcontaining key-value pairs for each enum variant.
§Examples
use enum_table::{EnumTable, Enumable};
use std::collections::HashMap;
#[derive(Enumable, Debug, PartialEq, Eq, Hash, Copy, Clone)]
enum Priority {
Low,
Medium,
High,
}
let mut hash_map = HashMap::new();
hash_map.insert(Priority::Low, 1);
hash_map.insert(Priority::Medium, 5);
hash_map.insert(Priority::High, 10);
let table = EnumTable::<Priority, i32, { Priority::COUNT }>::try_from_hash_map(hash_map)
.expect("HashMap should contain all variants");
assert_eq!(table.get(&Priority::Low), &1);
assert_eq!(table.get(&Priority::Medium), &5);
assert_eq!(table.get(&Priority::High), &10);// Example with missing variant
let mut incomplete_map = HashMap::new();
incomplete_map.insert(Priority::Low, 1);
incomplete_map.insert(Priority::Medium, 5);
// Missing Priority::High
let result = EnumTable::<Priority, i32, { Priority::COUNT }>::try_from_hash_map(incomplete_map);
assert!(result.is_none());Source§impl<K: Enumable + Ord, V, const N: usize> EnumTable<K, V, N>
impl<K: Enumable + Ord, V, const N: usize> EnumTable<K, V, N>
Sourcepub fn into_btree_map(self) -> BTreeMap<K, V>
pub fn into_btree_map(self) -> BTreeMap<K, V>
Converts the EnumTable into a BTreeMap.
This method consumes the EnumTable and creates a new BTreeMap with the same
key-value pairs. The resulting map will have keys sorted according to their Ord implementation.
§Examples
use enum_table::{EnumTable, Enumable};
use std::collections::BTreeMap;
#[derive(Enumable, Debug, PartialEq, Eq, Ord, PartialOrd, Copy, Clone)]
enum Level {
Beginner,
Intermediate,
Advanced,
}
let table = EnumTable::<Level, u32, { Level::COUNT }>::new_with_fn(|level| match level {
Level::Beginner => 100,
Level::Intermediate => 500,
Level::Advanced => 1000,
});
let btree_map = table.into_btree_map();
assert_eq!(btree_map.get(&Level::Beginner), Some(&100));
assert_eq!(btree_map.get(&Level::Intermediate), Some(&500));
assert_eq!(btree_map.get(&Level::Advanced), Some(&1000));
assert_eq!(btree_map.len(), 3);Sourcepub fn try_from_btree_map(map: BTreeMap<K, V>) -> Option<EnumTable<K, V, N>>
pub fn try_from_btree_map(map: BTreeMap<K, V>) -> Option<EnumTable<K, V, N>>
Creates an EnumTable from a BTreeMap.
Returns None if the BTreeMap doesn’t contain exactly one entry for each enum variant.
The BTreeMap must have exactly N entries where N is the number of enum variants.
§Arguments
map- ABTreeMapcontaining key-value pairs for each enum variant.
§Examples
use enum_table::{EnumTable, Enumable};
use std::collections::BTreeMap;
#[derive(Enumable, Debug, PartialEq, Eq, Ord, PartialOrd, Copy, Clone)]
enum Grade {
A,
B,
C,
}
let mut btree_map = BTreeMap::new();
btree_map.insert(Grade::A, 90.0);
btree_map.insert(Grade::B, 80.0);
btree_map.insert(Grade::C, 70.0);
let table = EnumTable::<Grade, f64, { Grade::COUNT }>::try_from_btree_map(btree_map)
.expect("BTreeMap should contain all variants");
assert_eq!(table.get(&Grade::A), &90.0);
assert_eq!(table.get(&Grade::B), &80.0);
assert_eq!(table.get(&Grade::C), &70.0);// Example with missing variant
let mut incomplete_map = BTreeMap::new();
incomplete_map.insert(Grade::A, 90.0);
incomplete_map.insert(Grade::B, 80.0);
// Missing Grade::C
let result = EnumTable::<Grade, f64, { Grade::COUNT }>::try_from_btree_map(incomplete_map);
assert!(result.is_none());Source§impl<K: Enumable, V, const N: usize> EnumTable<K, V, N>
impl<K: Enumable, V, const N: usize> EnumTable<K, V, N>
Sourcepub fn into_vec(self) -> Vec<(K, V)>
pub fn into_vec(self) -> Vec<(K, V)>
Converts the EnumTable into a Vec of key-value pairs.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Debug, PartialEq, Copy, Clone)]
enum Color {
Red,
Green,
Blue,
}
let table = EnumTable::<Color, &str, { Color::COUNT }>::new_with_fn(|color| match color {
Color::Red => "red",
Color::Green => "green",
Color::Blue => "blue",
});
let vec = table.into_vec();
assert!(vec.contains(&(Color::Red, "red")));
assert!(vec.contains(&(Color::Green, "green")));
assert!(vec.contains(&(Color::Blue, "blue")));
assert_eq!(vec.len(), 3);Sourcepub fn try_from_vec(vec: Vec<(K, V)>) -> Result<Self, EnumTableFromVecError<K>>
pub fn try_from_vec(vec: Vec<(K, V)>) -> Result<Self, EnumTableFromVecError<K>>
Creates an EnumTable from a Vec of key-value pairs.
Returns an error if the vector doesn’t contain exactly one entry for each enum variant.
§Arguments
vec- A vector containing key-value pairs for each enum variant.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Debug, PartialEq, Copy, Clone)]
enum Color {
Red,
Green,
Blue,
}
let vec = vec![
(Color::Red, "red"),
(Color::Green, "green"),
(Color::Blue, "blue"),
];
let table = EnumTable::<Color, &str, { Color::COUNT }>::try_from_vec(vec).unwrap();
assert_eq!(table.get(&Color::Red), &"red");
assert_eq!(table.get(&Color::Green), &"green");
assert_eq!(table.get(&Color::Blue), &"blue");Source§impl<K: Enumable, V, const N: usize> EnumTable<K, V, N>
impl<K: Enumable, V, const N: usize> EnumTable<K, V, N>
Sourcepub fn new_with_fn(f: impl FnMut(&K) -> V) -> Self
pub fn new_with_fn(f: impl FnMut(&K) -> V) -> Self
Sourcepub fn try_new_with_fn<E>(
f: impl FnMut(&K) -> Result<V, E>,
) -> Result<Self, (K, E)>
pub fn try_new_with_fn<E>( f: impl FnMut(&K) -> Result<V, E>, ) -> Result<Self, (K, E)>
Creates a new EnumTable using a function that returns a Result for each variant.
This method applies the provided closure to each variant of the enum. If the closure
returns Ok(value) for all variants, an EnumTable is constructed and returned as Ok(Self).
If the closure returns Err(e) for any variant, the construction is aborted and
Err((variant, e)) is returned, where variant is the enum variant that caused the error.
§Arguments
f- A closure that takes a reference to an enum variant and returns aResult<V, E>.
§Returns
Ok(Self)if all variants succeed.Err((variant, e))if any variant fails, containing the failing variant and the error.
Sourcepub fn checked_new_with_fn(f: impl FnMut(&K) -> Option<V>) -> Result<Self, K>
pub fn checked_new_with_fn(f: impl FnMut(&K) -> Option<V>) -> Result<Self, K>
Creates a new EnumTable using a function that returns an Option for each variant.
This method applies the provided closure to each variant of the enum. If the closure
returns Some(value) for all variants, an EnumTable is constructed and returned as Ok(Self).
If the closure returns None for any variant, the construction is aborted and
Err(variant) is returned, where variant is the enum variant that caused the failure.
§Arguments
f- A closure that takes a reference to an enum variant and returns anOption<V>.
§Returns
Ok(Self)if all variants succeed.Err(variant)if any variant fails, containing the failing variant.
Sourcepub fn get(&self, variant: &K) -> &V
pub fn get(&self, variant: &K) -> &V
Returns a reference to the value associated with the given enumeration variant.
Uses O(1) lookup via Enumable::variant_index.
§Arguments
variant- A reference to an enumeration variant.
Sourcepub fn get_mut(&mut self, variant: &K) -> &mut V
pub fn get_mut(&mut self, variant: &K) -> &mut V
Returns a mutable reference to the value associated with the given enumeration variant.
Uses O(1) lookup via Enumable::variant_index.
§Arguments
variant- A reference to an enumeration variant.
Sourcepub fn set(&mut self, variant: &K, value: V) -> V
pub fn set(&mut self, variant: &K, value: V) -> V
Sets the value associated with the given enumeration variant.
Uses O(1) lookup via Enumable::variant_index.
§Arguments
variant- A reference to an enumeration variant.value- The new value to associate with the variant.
§Returns
The old value associated with the variant.
Sourcepub const fn get_mut_const(&mut self, variant: &K) -> &mut V
pub const fn get_mut_const(&mut self, variant: &K) -> &mut V
Returns a mutable reference to the value associated with the given enumeration variant.
This is a const fn that uses binary search (O(log N)).
For O(1) access, use Self::get_mut.
§Arguments
variant- A reference to an enumeration variant.
Sourcepub const fn set_const(&mut self, variant: &K, value: V) -> V
pub const fn set_const(&mut self, variant: &K, value: V) -> V
Sets the value associated with the given enumeration variant.
This is a const fn that uses binary search (O(log N)).
For O(1) access, use Self::set.
§Arguments
variant- A reference to an enumeration variant.value- The new value to associate with the variant.
§Returns
The old value associated with the variant.
Sourcepub const fn len(&self) -> usize
pub const fn len(&self) -> usize
Returns the number of entries in the table (equal to the number of enum variants).
Sourcepub const fn is_empty(&self) -> bool
pub const fn is_empty(&self) -> bool
Returns true if the table has no entries (i.e., the enum has no variants).
Sourcepub const fn as_slice(&self) -> &[V]
pub const fn as_slice(&self) -> &[V]
Returns a reference to the underlying array of values.
Values are ordered by the sorted discriminant of the enum variants.
Sourcepub const fn as_mut_slice(&mut self) -> &mut [V]
pub const fn as_mut_slice(&mut self) -> &mut [V]
Returns a mutable reference to the underlying array of values.
Values are ordered by the sorted discriminant of the enum variants.
Sourcepub fn into_array(self) -> [V; N]
pub fn into_array(self) -> [V; N]
Consumes the table and returns the underlying array of values.
Values are ordered by the sorted discriminant of the enum variants.
Sourcepub fn zip<U, W>(
self,
other: EnumTable<K, U, N>,
f: impl FnMut(V, U) -> W,
) -> EnumTable<K, W, N>
pub fn zip<U, W>( self, other: EnumTable<K, U, N>, f: impl FnMut(V, U) -> W, ) -> EnumTable<K, W, N>
Combines two EnumTables into a new one by applying a function to each pair of values.
§Arguments
other- AnotherEnumTablewith the same key type.f- A closure that takes two values and returns a new value.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Copy, Clone)]
enum Stat {
Hp,
Attack,
Defense,
}
let base = EnumTable::<Stat, i32, { Stat::COUNT }>::new_with_fn(|s| match s {
Stat::Hp => 100,
Stat::Attack => 50,
Stat::Defense => 30,
});
let bonus = EnumTable::<Stat, i32, { Stat::COUNT }>::new_with_fn(|s| match s {
Stat::Hp => 20,
Stat::Attack => 10,
Stat::Defense => 5,
});
let total = base.zip(bonus, |a, b| a + b);
assert_eq!(total.get(&Stat::Hp), &120);
assert_eq!(total.get(&Stat::Attack), &60);
assert_eq!(total.get(&Stat::Defense), &35);Sourcepub fn map<U>(self, f: impl FnMut(V) -> U) -> EnumTable<K, U, N>
pub fn map<U>(self, f: impl FnMut(V) -> U) -> EnumTable<K, U, N>
Transforms all values in the table using the provided function.
This method consumes the table and creates a new one with values transformed by the given closure.
§Arguments
f- A closure that takes an owned value and returns a new value.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Copy, Clone)]
enum Size {
Small,
Medium,
Large,
}
let table = EnumTable::<Size, i32, { Size::COUNT }>::new_with_fn(|size| match size {
Size::Small => 1,
Size::Medium => 2,
Size::Large => 3,
});
let doubled = table.map(|value| value * 2);
assert_eq!(doubled.get(&Size::Small), &2);
assert_eq!(doubled.get(&Size::Medium), &4);
assert_eq!(doubled.get(&Size::Large), &6);Sourcepub fn map_with_key<U>(self, f: impl FnMut(&K, V) -> U) -> EnumTable<K, U, N>
pub fn map_with_key<U>(self, f: impl FnMut(&K, V) -> U) -> EnumTable<K, U, N>
Transforms all values in the table using the provided function, with access to the key.
This method consumes the table and creates a new one with values transformed by the given closure, which receives both the key and the value.
§Arguments
f- A closure that takes a key reference and an owned value, and returns a new value.
Sourcepub fn map_mut(&mut self, f: impl FnMut(&mut V))
pub fn map_mut(&mut self, f: impl FnMut(&mut V))
Transforms all values in the table in-place using the provided function.
§Arguments
f- A closure that takes a mutable reference to a value and modifies it.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Copy, Clone)]
enum Level {
Low,
Medium,
High,
}
let mut table = EnumTable::<Level, i32, { Level::COUNT }>::new_with_fn(|level| match level {
Level::Low => 10,
Level::Medium => 20,
Level::High => 30,
});
table.map_mut(|value| *value += 5);
assert_eq!(table.get(&Level::Low), &15);
assert_eq!(table.get(&Level::Medium), &25);
assert_eq!(table.get(&Level::High), &35);Source§impl<K: Enumable, V, const N: usize> EnumTable<K, Option<V>, N>
impl<K: Enumable, V, const N: usize> EnumTable<K, Option<V>, N>
Sourcepub const fn new_fill_with_none() -> Self
pub const fn new_fill_with_none() -> Self
Creates a new EnumTable with None values for each variant.
Sourcepub fn clear_to_none(&mut self)
pub fn clear_to_none(&mut self)
Clears the table, setting each value to None.
Sourcepub fn remove(&mut self, variant: &K) -> Option<V>
pub fn remove(&mut self, variant: &K) -> Option<V>
Removes and returns the value associated with the given enumeration variant,
leaving None in its place.
Uses O(1) lookup via Enumable::variant_index.
§Arguments
variant- A reference to an enumeration variant.
§Returns
The previous value, or None if the slot was already empty.
Sourcepub const fn remove_const(&mut self, variant: &K) -> Option<V>
pub const fn remove_const(&mut self, variant: &K) -> Option<V>
Removes and returns the value associated with the given enumeration variant,
leaving None in its place.
This is a const fn that uses binary search (O(log N)).
For O(1) access, use Self::remove.
§Arguments
variant- A reference to an enumeration variant.
§Returns
The previous value, or None if the slot was already empty.
Source§impl<K: Enumable, V: Copy, const N: usize> EnumTable<K, V, N>
impl<K: Enumable, V: Copy, const N: usize> EnumTable<K, V, N>
Sourcepub const fn new_fill_with_copy(value: V) -> Self
pub const fn new_fill_with_copy(value: V) -> Self
Creates a new EnumTable with the same copied value for each variant.
This method initializes the table with the same value for each
variant of the enumeration. The value must implement Copy.
§Arguments
value- The value to copy for each enum variant.
§Examples
use enum_table::{EnumTable, Enumable};
#[derive(Enumable, Copy, Clone)]
enum Status {
Active,
Inactive,
Pending,
}
let table = EnumTable::<Status, i32, { Status::COUNT }>::new_fill_with_copy(42);
assert_eq!(table.get(&Status::Active), &42);
assert_eq!(table.get(&Status::Inactive), &42);
assert_eq!(table.get(&Status::Pending), &42);Source§impl<K: Enumable, V: Default, const N: usize> EnumTable<K, V, N>
impl<K: Enumable, V: Default, const N: usize> EnumTable<K, V, N>
Sourcepub fn new_fill_with_default() -> Self
pub fn new_fill_with_default() -> Self
Creates a new EnumTable with default values for each variant.
This method initializes the table with the default value of type V for each
variant of the enumeration.
Sourcepub fn clear_to_default(&mut self)
pub fn clear_to_default(&mut self)
Clears the table, setting each value to its default.
Trait Implementations§
Source§impl<'a, K: Enumable, V: Copy, const N: usize> Extend<(&'a K, &'a V)> for EnumTable<K, V, N>
impl<'a, K: Enumable, V: Copy, const N: usize> Extend<(&'a K, &'a V)> for EnumTable<K, V, N>
Source§fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = (&'a K, &'a V)>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)Source§impl<K: Enumable, V, const N: usize> Extend<(K, V)> for EnumTable<K, V, N>
impl<K: Enumable, V, const N: usize> Extend<(K, V)> for EnumTable<K, V, N>
Source§fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = (K, V)>>(&mut self, iter: I)
Source§fn extend_one(&mut self, item: A)
fn extend_one(&mut self, item: A)
extend_one)Source§fn extend_reserve(&mut self, additional: usize)
fn extend_reserve(&mut self, additional: usize)
extend_one)