pub struct TriHashMap<T: TriHashItem, S = DefaultHashBuilder, A: Allocator = Global> { /* private fields */ }
Expand description
A 1:1:1 (trijective) map for three keys and a value.
The storage mechanism is a fast hash table of integer indexes to items, with these indexes stored in three hashmaps. This allows for efficient lookups by any of the three keys, while preventing duplicates.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
// Implement TriHashItem to define the three key types.
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
// Create a TriHashMap and insert items.
let mut people = TriHashMap::new();
people
.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
// Lookup by any of the three keys.
let person = people.get1(&1).unwrap();
assert_eq!(person.name, "Alice");
let person = people.get2("alice@example.com").unwrap();
assert_eq!(person.id, 1);
let person = people.get3("555-1234").unwrap();
assert_eq!(person.email, "alice@example.com");
Implementations§
Source§impl<T: TriHashItem> TriHashMap<T>
impl<T: TriHashItem> TriHashMap<T>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new, empty TriHashMap
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let map: TriHashMap<Person> = TriHashMap::new();
assert!(map.is_empty());
assert_eq!(map.len(), 0);
Sourcepub fn with_capacity(capacity: usize) -> Self
pub fn with_capacity(capacity: usize) -> Self
Creates a new TriHashMap
with the given capacity.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let map: TriHashMap<Person> = TriHashMap::with_capacity(10);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: TriHashItem, S: Clone + BuildHasher> TriHashMap<T, S>
impl<T: TriHashItem, S: Clone + BuildHasher> TriHashMap<T, S>
Sourcepub fn with_hasher(hasher: S) -> Self
pub fn with_hasher(hasher: S) -> Self
Creates a new, empty TriHashMap
with the given hasher.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let map: TriHashMap<Person, RandomState> =
TriHashMap::with_hasher(RandomState::new());
assert!(map.is_empty());
Sourcepub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self
pub fn with_capacity_and_hasher(capacity: usize, hasher: S) -> Self
Creates a new TriHashMap
with the given capacity and hasher.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let map: TriHashMap<Person, RandomState> =
TriHashMap::with_capacity_and_hasher(10, RandomState::new());
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: TriHashItem, A: Clone + Allocator> TriHashMap<T, DefaultHashBuilder, A>
impl<T: TriHashItem, A: Clone + Allocator> TriHashMap<T, DefaultHashBuilder, A>
Sourcepub fn new_in(alloc: A) -> Self
pub fn new_in(alloc: A) -> Self
Creates a new empty TriHashMap
using the given allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{TriHashMap, TriHashItem, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
// Create a new TriHashMap using the allocator.
let map: TriHashMap<Person, _, &bumpalo::Bump> = TriHashMap::new_in(&bump);
assert!(map.is_empty());
Sourcepub fn with_capacity_in(capacity: usize, alloc: A) -> Self
pub fn with_capacity_in(capacity: usize, alloc: A) -> Self
Creates an empty TriHashMap
with the specified capacity using the given
allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{TriHashMap, TriHashItem, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
// Create a new TriHashMap with capacity using the allocator.
let map: TriHashMap<Person, _, &bumpalo::Bump> = TriHashMap::with_capacity_in(10, &bump);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: TriHashItem, S: Clone + BuildHasher, A: Clone + Allocator> TriHashMap<T, S, A>
impl<T: TriHashItem, S: Clone + BuildHasher, A: Clone + Allocator> TriHashMap<T, S, A>
Sourcepub fn with_hasher_in(hasher: S, alloc: A) -> Self
pub fn with_hasher_in(hasher: S, alloc: A) -> Self
Creates a new, empty TriHashMap
with the given hasher and allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
let hasher = RandomState::new();
// Create a new TriHashMap with hasher using the allocator.
let map: TriHashMap<Person, _, &bumpalo::Bump> =
TriHashMap::with_hasher_in(hasher, &bump);
assert!(map.is_empty());
Sourcepub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> Self
pub fn with_capacity_and_hasher_in(capacity: usize, hasher: S, alloc: A) -> Self
Creates a new TriHashMap
with the given capacity, hasher, and
allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
use std::collections::hash_map::RandomState;
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
let hasher = RandomState::new();
// Create a new TriHashMap with capacity and hasher using the allocator.
let map: TriHashMap<Person, _, &bumpalo::Bump> =
TriHashMap::with_capacity_and_hasher_in(10, hasher, &bump);
assert!(map.capacity() >= 10);
assert!(map.is_empty());
Source§impl<T: TriHashItem, S: Clone + BuildHasher, A: Allocator> TriHashMap<T, S, A>
impl<T: TriHashItem, S: Clone + BuildHasher, A: Allocator> TriHashMap<T, S, A>
Sourcepub fn allocator(&self) -> &A
pub fn allocator(&self) -> &A
Returns the allocator.
Requires the allocator-api2
feature to be enabled.
§Examples
Using the bumpalo
allocator:
use iddqd::{TriHashMap, TriHashItem, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
// Define a new allocator.
let bump = bumpalo::Bump::new();
// Create a new TriHashMap using the allocator.
let map: TriHashMap<Person, _, &bumpalo::Bump> = TriHashMap::new_in(&bump);
// Access the allocator.
let allocator = map.allocator();
Sourcepub fn capacity(&self) -> usize
pub fn capacity(&self) -> usize
Returns the currently allocated capacity of the map.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let map: TriHashMap<Person> = TriHashMap::with_capacity(10);
assert!(map.capacity() >= 10);
Sourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns true if the map is empty.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
assert!(map.is_empty());
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert!(!map.is_empty());
Sourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of items in the map.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
assert_eq!(map.len(), 0);
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
map.insert_unique(Person {
id: 2,
email: "bob@example.com".to_string(),
phone: "555-5678".to_string(),
name: "Bob".to_string(),
})
.unwrap();
assert_eq!(map.len(), 2);
Sourcepub fn iter(&self) -> Iter<'_, T> ⓘ
pub fn iter(&self) -> Iter<'_, T> ⓘ
Iterates over the items in the map.
Similar to HashMap
, the iteration order is arbitrary and not
guaranteed to be stable.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
map.insert_unique(Person {
id: 2,
email: "bob@example.com".to_string(),
phone: "555-5678".to_string(),
name: "Bob".to_string(),
})
.unwrap();
let mut count = 0;
for person in map.iter() {
assert!(person.id == 1 || person.id == 2);
count += 1;
}
assert_eq!(count, 2);
Sourcepub fn iter_mut(&mut self) -> IterMut<'_, T, S, A> ⓘ
pub fn iter_mut(&mut self) -> IterMut<'_, T, S, A> ⓘ
Iterates over the items in the map, allowing for mutation.
Similar to HashMap
, the iteration order is arbitrary and not
guaranteed to be stable.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
for mut person in map.iter_mut() {
person.name.push_str(" Updated");
}
let person = map.get1(&1).unwrap();
assert_eq!(person.name, "Alice Updated");
Sourcepub fn insert_overwrite(&mut self, value: T) -> Vec<T>
pub fn insert_overwrite(&mut self, value: T) -> Vec<T>
Inserts a value into the map, removing any conflicting items and returning a list of those items.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
// First insertion - no conflicts
let overwritten = map.insert_overwrite(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
});
assert!(overwritten.is_empty());
// Overwrite with same id - returns the old item
let overwritten = map.insert_overwrite(Person {
id: 1,
email: "alice.new@example.com".to_string(),
phone: "555-9999".to_string(),
name: "Alice New".to_string(),
});
assert_eq!(overwritten.len(), 1);
assert_eq!(overwritten[0].name, "Alice");
Sourcepub fn insert_unique(&mut self, value: T) -> Result<(), DuplicateItem<T, &T>>
pub fn insert_unique(&mut self, value: T) -> Result<(), DuplicateItem<T, &T>>
Inserts a value into the set, returning an error if any duplicates were added.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
// Successful insertion
assert!(
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.is_ok()
);
assert!(
map.insert_unique(Person {
id: 2,
email: "bob@example.com".to_string(),
phone: "555-5678".to_string(),
name: "Bob".to_string(),
})
.is_ok()
);
// Duplicate key1
assert!(
map.insert_unique(Person {
id: 1,
email: "charlie@example.com".to_string(),
phone: "555-9999".to_string(),
name: "Charlie".to_string(),
})
.is_err()
);
// Duplicate key2
assert!(
map.insert_unique(Person {
id: 3,
email: "alice@example.com".to_string(),
phone: "555-7777".to_string(),
name: "Alice2".to_string(),
})
.is_err()
);
// Duplicate key3
assert!(
map.insert_unique(Person {
id: 4,
email: "dave@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Dave".to_string(),
})
.is_err()
);
Sourcepub fn contains_key_unique<'a, Q1, Q2, Q3>(
&'a self,
key1: &Q1,
key2: &Q2,
key3: &Q3,
) -> bool
pub fn contains_key_unique<'a, Q1, Q2, Q3>( &'a self, key1: &Q1, key2: &Q2, key3: &Q3, ) -> bool
Returns true if the map contains a single item that matches all three keys.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
}).unwrap();
map.insert_unique(Person {
id: 2,
email: "bob@example.com".to_string(),
phone: "555-5678".to_string(),
name: "Bob".to_string(),
}).unwrap();
assert!(map.contains_key_unique(&1, &"alice@example.com", &"555-1234"));
assert!(map.contains_key_unique(&2, &"bob@example.com", &"555-5678"));
assert!(!map.contains_key_unique(&1, &"bob@example.com", &"555-1234")); // key1 exists but key2 doesn't match
assert!(!map.contains_key_unique(&3, &"charlie@example.com", &"555-9999")); // none of the keys exist
Sourcepub fn get_unique<'a, Q1, Q2, Q3>(
&'a self,
key1: &Q1,
key2: &Q2,
key3: &Q3,
) -> Option<&'a T>
pub fn get_unique<'a, Q1, Q2, Q3>( &'a self, key1: &Q1, key2: &Q2, key3: &Q3, ) -> Option<&'a T>
Gets a reference to the unique item associated with the given key1
,
key2
, and key3
, if it exists.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
// All three keys must match
assert_eq!(
map.get_unique(&1, &"alice@example.com", &"555-1234").unwrap().name,
"Alice"
);
// If any key doesn't match, returns None
assert!(map.get_unique(&1, &"wrong@example.com", &"555-1234").is_none());
assert!(map.get_unique(&2, &"alice@example.com", &"555-1234").is_none());
Sourcepub fn get_mut_unique<'a, Q1, Q2, Q3>(
&'a mut self,
key1: &Q1,
key2: &Q2,
key3: &Q3,
) -> Option<RefMut<'a, T, S>>
pub fn get_mut_unique<'a, Q1, Q2, Q3>( &'a mut self, key1: &Q1, key2: &Q2, key3: &Q3, ) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the unique item associated with the given
key1
, key2
, and key3
, if it exists.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
// Modify the item through the mutable reference
if let Some(mut person) =
map.get_mut_unique(&1, &"alice@example.com", &"555-1234")
{
person.name = "Alice Updated".to_string();
}
// Verify the change
assert_eq!(map.get1(&1).unwrap().name, "Alice Updated");
Sourcepub fn remove_unique<'a, Q1, Q2, Q3>(
&'a mut self,
key1: &Q1,
key2: &Q2,
key3: &Q3,
) -> Option<T>
pub fn remove_unique<'a, Q1, Q2, Q3>( &'a mut self, key1: &Q1, key2: &Q2, key3: &Q3, ) -> Option<T>
Removes the item uniquely identified by key1
, key2
, and key3
, if
it exists.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
// Remove the item using all three keys
let removed = map.remove_unique(&1, &"alice@example.com", &"555-1234");
assert!(removed.is_some());
assert_eq!(removed.unwrap().name, "Alice");
// Map is now empty
assert!(map.is_empty());
// Trying to remove again returns None
assert!(map.remove_unique(&1, &"alice@example.com", &"555-1234").is_none());
Sourcepub fn contains_key1<'a, Q>(&'a self, key1: &Q) -> bool
pub fn contains_key1<'a, Q>(&'a self, key1: &Q) -> bool
Returns true if the map contains the given key1
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert!(map.contains_key1(&1));
assert!(!map.contains_key1(&2));
Sourcepub fn get1<'a, Q>(&'a self, key1: &Q) -> Option<&'a T>
pub fn get1<'a, Q>(&'a self, key1: &Q) -> Option<&'a T>
Gets a reference to the value associated with the given key1
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert_eq!(map.get1(&1).unwrap().name, "Alice");
assert!(map.get1(&2).is_none());
Sourcepub fn get1_mut<'a, Q>(&'a mut self, key1: &Q) -> Option<RefMut<'a, T, S>>
pub fn get1_mut<'a, Q>(&'a mut self, key1: &Q) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the value associated with the given key1
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
if let Some(mut person) = map.get1_mut(&1) {
person.name = "Alice Updated".to_string();
}
assert_eq!(map.get1(&1).unwrap().name, "Alice Updated");
Sourcepub fn remove1<'a, Q>(&'a mut self, key1: &Q) -> Option<T>
pub fn remove1<'a, Q>(&'a mut self, key1: &Q) -> Option<T>
Removes an item from the map by its key1
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
let removed = map.remove1(&1);
assert!(removed.is_some());
assert_eq!(removed.unwrap().name, "Alice");
assert!(map.is_empty());
Sourcepub fn contains_key2<'a, Q>(&'a self, key2: &Q) -> bool
pub fn contains_key2<'a, Q>(&'a self, key2: &Q) -> bool
Returns true if the map contains the given key2
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert!(map.contains_key2("alice@example.com"));
assert!(!map.contains_key2("bob@example.com"));
Sourcepub fn get2<'a, Q>(&'a self, key2: &Q) -> Option<&'a T>
pub fn get2<'a, Q>(&'a self, key2: &Q) -> Option<&'a T>
Gets a reference to the value associated with the given key2
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert_eq!(map.get2("alice@example.com").unwrap().name, "Alice");
assert!(map.get2("bob@example.com").is_none());
Sourcepub fn get2_mut<'a, Q>(&'a mut self, key2: &Q) -> Option<RefMut<'a, T, S>>
pub fn get2_mut<'a, Q>(&'a mut self, key2: &Q) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the value associated with the given key2
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
if let Some(mut person) = map.get2_mut("alice@example.com") {
person.name = "Alice Updated".to_string();
}
assert_eq!(map.get2("alice@example.com").unwrap().name, "Alice Updated");
Sourcepub fn remove2<'a, Q>(&'a mut self, key2: &Q) -> Option<T>
pub fn remove2<'a, Q>(&'a mut self, key2: &Q) -> Option<T>
Removes an item from the map by its key2
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
let removed = map.remove2("alice@example.com");
assert!(removed.is_some());
assert_eq!(removed.unwrap().name, "Alice");
assert!(map.is_empty());
Sourcepub fn contains_key3<'a, Q>(&'a self, key3: &Q) -> bool
pub fn contains_key3<'a, Q>(&'a self, key3: &Q) -> bool
Returns true if the map contains the given key3
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert!(map.contains_key3("555-1234"));
assert!(!map.contains_key3("555-5678"));
Sourcepub fn get3<'a, Q>(&'a self, key3: &Q) -> Option<&'a T>
pub fn get3<'a, Q>(&'a self, key3: &Q) -> Option<&'a T>
Gets a reference to the value associated with the given key3
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
assert_eq!(map.get3("555-1234").unwrap().name, "Alice");
assert!(map.get3("555-5678").is_none());
Sourcepub fn get3_mut<'a, Q>(&'a mut self, key3: &Q) -> Option<RefMut<'a, T, S>>
pub fn get3_mut<'a, Q>(&'a mut self, key3: &Q) -> Option<RefMut<'a, T, S>>
Gets a mutable reference to the value associated with the given key3
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
if let Some(mut person) = map.get3_mut("555-1234") {
person.name = "Alice Updated".to_string();
}
assert_eq!(map.get3("555-1234").unwrap().name, "Alice Updated");
Sourcepub fn remove3<'a, Q>(&'a mut self, key3: &Q) -> Option<T>
pub fn remove3<'a, Q>(&'a mut self, key3: &Q) -> Option<T>
Removes an item from the map by its key3
.
§Examples
use iddqd::{TriHashItem, TriHashMap, tri_upcast};
#[derive(Debug, PartialEq, Eq)]
struct Person {
id: u32,
email: String,
phone: String,
name: String,
}
impl TriHashItem for Person {
type K1<'a> = u32;
type K2<'a> = &'a str;
type K3<'a> = &'a str;
fn key1(&self) -> Self::K1<'_> {
self.id
}
fn key2(&self) -> Self::K2<'_> {
&self.email
}
fn key3(&self) -> Self::K3<'_> {
&self.phone
}
tri_upcast!();
}
let mut map = TriHashMap::new();
map.insert_unique(Person {
id: 1,
email: "alice@example.com".to_string(),
phone: "555-1234".to_string(),
name: "Alice".to_string(),
})
.unwrap();
let removed = map.remove3("555-1234");
assert!(removed.is_some());
assert_eq!(removed.unwrap().name, "Alice");
assert!(map.is_empty());
Trait Implementations§
Source§impl<T: Clone + TriHashItem, S: Clone, A: Clone + Allocator> Clone for TriHashMap<T, S, A>
impl<T: Clone + TriHashItem, S: Clone, A: Clone + Allocator> Clone for TriHashMap<T, S, A>
Source§fn clone(&self) -> TriHashMap<T, S, A>
fn clone(&self) -> TriHashMap<T, S, A>
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source
. Read moreSource§impl<'a, T, S, A: Allocator> Debug for TriHashMap<T, S, A>
impl<'a, T, S, A: Allocator> Debug for TriHashMap<T, S, A>
Source§impl<T: TriHashItem, S: Default, A: Allocator + Default> Default for TriHashMap<T, S, A>
impl<T: TriHashItem, S: Default, A: Allocator + Default> Default for TriHashMap<T, S, A>
Source§impl<T: TriHashItem, S: Clone + BuildHasher, A: Allocator> Extend<T> for TriHashMap<T, S, A>
The Extend
implementation overwrites duplicates. In the future, there will
also be an extend_unique
method that will return an error.
impl<T: TriHashItem, S: Clone + BuildHasher, A: Allocator> Extend<T> for TriHashMap<T, S, A>
The Extend
implementation overwrites duplicates. In the future, there will
also be an extend_unique
method that will return an error.
Source§fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I)
fn extend<I: IntoIterator<Item = T>>(&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<T: TriHashItem, S: Default + Clone + BuildHasher, A: Default + Allocator> FromIterator<T> for TriHashMap<T, S, A>
The FromIterator
implementation for TriHashMap
overwrites duplicate
items.
impl<T: TriHashItem, S: Default + Clone + BuildHasher, A: Default + Allocator> FromIterator<T> for TriHashMap<T, S, A>
The FromIterator
implementation for TriHashMap
overwrites duplicate
items.
Source§fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self
Source§impl<'a, T: TriHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a TriHashMap<T, S, A>
impl<'a, T: TriHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a TriHashMap<T, S, A>
Source§impl<'a, T: TriHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a mut TriHashMap<T, S, A>
impl<'a, T: TriHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for &'a mut TriHashMap<T, S, A>
Source§impl<T: TriHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for TriHashMap<T, S, A>
impl<T: TriHashItem, S: Clone + BuildHasher, A: Allocator> IntoIterator for TriHashMap<T, S, A>
Source§impl<T: TriHashItem + PartialEq, S: Clone + BuildHasher, A: Allocator> PartialEq for TriHashMap<T, S, A>
impl<T: TriHashItem + PartialEq, S: Clone + BuildHasher, A: Allocator> PartialEq for TriHashMap<T, S, A>
impl<T: TriHashItem + Eq, S: Clone + BuildHasher, A: Allocator> Eq for TriHashMap<T, S, A>
Auto Trait Implementations§
impl<T, S, A> Freeze for TriHashMap<T, S, A>
impl<T, S, A> RefUnwindSafe for TriHashMap<T, S, A>
impl<T, S, A> Send for TriHashMap<T, S, A>
impl<T, S, A> Sync for TriHashMap<T, S, A>
impl<T, S, A> Unpin for TriHashMap<T, S, A>
impl<T, S, A> UnwindSafe for TriHashMap<T, S, A>
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<Q, K> Equivalent<K> for Q
impl<Q, K> Equivalent<K> for Q
§fn equivalent(&self, key: &K) -> bool
fn equivalent(&self, key: &K) -> bool
key
and return true
if they are equal.