kast_refmap/
lib.rs

1use std::collections::HashMap;
2use std::hash::Hash;
3use std::rc::Rc;
4use std::sync::Arc;
5
6pub trait Ref: Clone {
7    fn is_same_ref(&self, other: &Self) -> bool;
8    fn hash_ref(&self, hasher: &mut impl std::hash::Hasher);
9}
10
11impl<T> Ref for Rc<T> {
12    fn is_same_ref(&self, other: &Self) -> bool {
13        Rc::ptr_eq(self, other)
14    }
15    fn hash_ref(&self, hasher: &mut impl std::hash::Hasher) {
16        Rc::as_ptr(self).hash(hasher)
17    }
18}
19
20impl<T> Ref for Arc<T> {
21    fn is_same_ref(&self, other: &Self) -> bool {
22        Arc::ptr_eq(self, other)
23    }
24    fn hash_ref(&self, hasher: &mut impl std::hash::Hasher) {
25        Arc::as_ptr(self).hash(hasher)
26    }
27}
28
29impl<T> Ref for &'_ T {
30    fn is_same_ref(&self, other: &Self) -> bool {
31        std::ptr::eq(*self, *other)
32    }
33    fn hash_ref(&self, hasher: &mut impl std::hash::Hasher) {
34        (*self as *const T).hash(hasher)
35    }
36}
37
38#[derive(Clone)]
39struct RefKey<K: Ref>(K);
40
41impl<K: Ref> PartialEq for RefKey<K> {
42    fn eq(&self, other: &Self) -> bool {
43        self.0.is_same_ref(&other.0)
44    }
45}
46impl<K: Ref> Eq for RefKey<K> {}
47
48impl<K: Ref> Hash for RefKey<K> {
49    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
50        self.0.hash_ref(state)
51    }
52}
53
54pub struct RefMap<K: Ref, V>(HashMap<RefKey<K>, V>);
55
56impl<K: Ref, V: Clone> Clone for RefMap<K, V> {
57    fn clone(&self) -> Self {
58        Self(self.0.clone())
59    }
60}
61
62impl<K: Ref, V> Default for RefMap<K, V> {
63    fn default() -> Self {
64        Self::new()
65    }
66}
67
68impl<K: Ref, V> RefMap<K, V> {
69    pub fn new() -> Self {
70        Self(HashMap::new())
71    }
72    pub fn insert(&mut self, key: K, value: V) {
73        self.0.insert(RefKey(key), value);
74    }
75    pub fn get(&self, key: &K) -> Option<&V> {
76        self.0.get(&RefKey(key.clone()))
77    }
78    pub fn get_mut(&mut self, key: K) -> Option<&mut V> {
79        self.0.get_mut(&RefKey(key))
80    }
81    pub fn iter(&self) -> impl Iterator<Item = (&K, &V)> {
82        self.0.iter().map(|(RefKey(key), value)| (key, value))
83    }
84    pub fn iter_mut(&mut self) -> impl Iterator<Item = (&K, &mut V)> {
85        self.0.iter_mut().map(|(RefKey(key), value)| (key, value))
86    }
87}
88
89impl<K: Ref + 'static, V: 'static> IntoIterator for RefMap<K, V> {
90    type Item = (K, V);
91    type IntoIter = Box<dyn Iterator<Item = (K, V)>>; // TODO impl or concrete
92    fn into_iter(self) -> Self::IntoIter {
93        Box::new(self.0.into_iter().map(|(RefKey(key), value)| (key, value)))
94    }
95}