wachter_storage/
handle_map.rs1use core::hash::Hash;
2use std::{collections::HashMap, marker::PhantomData};
3
4#[derive(Debug)]
5pub struct Handle<V> {
6 handle: usize,
7 marker: PhantomData<V>,
8}
9
10impl<V> Handle<V> {
13 fn new(handle: usize) -> Self {
14 Self {
15 handle,
16 marker: PhantomData,
17 }
18 }
19}
20
21impl<V> PartialEq for Handle<V> {
22 fn eq(&self, other: &Self) -> bool {
23 self.handle == other.handle
24 }
25}
26
27impl<V> Eq for Handle<V> {}
28impl<V> Hash for Handle<V> {
29 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
30 state.write_usize(self.handle)
31 }
32}
33impl<V> Clone for Handle<V> {
34 fn clone(&self) -> Self {
35 Handle::new(self.handle)
36 }
37}
38impl<V> Copy for Handle<V> {}
39
40#[derive(Debug)]
41pub struct HandleMap<V> {
42 storage: HashMap<Handle<V>, V>,
44}
45
46impl<V> HandleMap<V> {
47 pub fn new() -> Self {
48 Self {
49 storage: HashMap::new(),
50 }
51 }
52
53 pub fn insert(&mut self, value: V) -> Handle<V> {
54 self.register(value)
55 }
56
57 pub fn get(&self, handle: Handle<V>) -> Option<&V> {
58 self.storage.get(&handle)
59 }
60
61 pub fn get_mut(&mut self, handle: Handle<V>) -> Option<&mut V> {
62 self.storage.get_mut(&handle)
63 }
64
65 pub fn remove(&mut self, handle: Handle<V>) -> Option<V> {
66 self.storage.remove(&handle)
67 }
68
69 fn register(&mut self, value: V) -> Handle<V> {
70 let id = self.storage.len();
71 let handle = Handle::new(id);
72 self.storage.insert(handle, value);
73 handle
74 }
75}
76
77#[cfg(test)]
78mod test {
79 use super::*;
80
81 #[test]
82 fn insert_and_retrieve() {
83 let mut map: HandleMap<String> = HandleMap::new();
84 let hello = "Hello".to_string();
85 let handle_1 = map.insert(hello.clone());
86 let _ = map.insert("World".to_string());
87 let res = map.get(handle_1);
88 assert!(res.is_some());
89 assert_eq!(&hello, res.unwrap());
90 }
91
92 #[test]
93 fn get_missing() {
94 let mut map: HandleMap<String> = HandleMap::new();
95 let hello = "Hello".to_string();
96 let handle_1 = map.insert(hello.clone());
97 map.remove(handle_1);
98 let res = map.get(handle_1);
99 assert!(res.is_none());
100 }
101}