1use std::marker::PhantomData;
3
4use crate::bounds::{Bounds, HasBounds};
5use crate::typedvalue::TypedMapValue;
6use crate::TypedMapKey;
7use crate::{dashmap::RefMut, typedkey::TypedKey};
8
9const INVALID_ENTRY: &str = "Broken TypedDashMap: invalid entry";
10
11pub struct OccupiedEntry<'a, K, KB, VB, Marker>
12where
13 K: 'static + TypedMapKey<Marker>,
14 KB: 'static + Bounds + HasBounds<K>,
15 VB: 'static + Bounds + HasBounds<K::Value>,
16{
17 base: dashmap::mapref::entry::OccupiedEntry<'a, TypedKey<KB>, TypedMapValue<VB>>,
18 _phantom: PhantomData<Marker>,
19 _phantom_key: PhantomData<K>,
20}
21
22impl<'a, K, KB, VB, Marker> OccupiedEntry<'a, K, KB, VB, Marker>
23where
24 K: 'static + TypedMapKey<Marker>,
25 KB: 'static + Bounds + HasBounds<K>,
26 VB: 'static + Bounds + HasBounds<K::Value>,
27{
28 #[inline]
29 pub fn into_ref(self) -> RefMut<'a, Marker, K, KB, VB> {
30 let refmut = self.base.into_ref();
31
32 RefMut(refmut, PhantomData, PhantomData)
33 }
34
35 #[inline]
36 pub fn key(&self) -> &K {
37 self.base.key().downcast_ref::<K>().expect(INVALID_ENTRY)
38 }
39
40 #[inline]
41 pub fn remove_entry(self) -> (K, K::Value) {
42 let (k, v) = self.base.remove_entry();
43 let v = v.downcast::<K::Value>().expect(INVALID_ENTRY);
44 let k = k.downcast::<K>().expect(INVALID_ENTRY);
45 (k, v)
46 }
47
48 #[inline]
49 pub fn get(&self) -> &K::Value {
50 self.base
51 .get()
52 .downcast_ref::<K::Value>()
53 .expect(INVALID_ENTRY)
54 }
55
56 #[inline]
57 pub fn get_mut(&mut self) -> &mut K::Value {
58 self.base
59 .get_mut()
60 .downcast_mut::<K::Value>()
61 .expect(INVALID_ENTRY)
62 }
63
64 #[inline]
65 pub fn insert(&mut self, value: K::Value) -> K::Value {
66 let value = TypedMapValue::from_value(value);
67 self.base
68 .insert(value)
69 .downcast::<K::Value>()
70 .expect(INVALID_ENTRY)
71 }
72
73 #[inline]
74 pub fn remove(self) -> K::Value {
75 self.base
76 .remove()
77 .downcast::<K::Value>()
78 .expect(INVALID_ENTRY)
79 }
80}
81
82pub struct VacantEntry<'a, K, KB, VB, Marker>
83where
84 K: 'static + TypedMapKey<Marker>,
85 KB: 'static + Bounds + HasBounds<K>,
86 VB: 'static + Bounds + HasBounds<K::Value>,
87{
88 base: dashmap::mapref::entry::VacantEntry<'a, TypedKey<KB>, TypedMapValue<VB>>,
89 _phantom: PhantomData<Marker>,
90 _phantom_key: PhantomData<K>,
91}
92
93impl<'a, K, KB, VB, Marker> VacantEntry<'a, K, KB, VB, Marker>
94where
95 K: 'static + TypedMapKey<Marker>,
96 KB: 'static + Bounds + HasBounds<K>,
97 VB: 'static + Bounds + HasBounds<K::Value>,
98{
99 #[inline]
100 pub fn key(&self) -> &K {
101 self.base.key().downcast_ref::<K>().expect(INVALID_ENTRY)
102 }
103
104 #[inline]
105 pub fn into_key(self) -> K {
106 self.base.into_key().downcast::<K>().expect(INVALID_ENTRY)
107 }
108
109 #[inline]
110 pub fn insert(self, value: K::Value) -> RefMut<'a, Marker, K, KB, VB> {
111 let value = TypedMapValue::from_value(value);
112 let refmut = self.base.insert(value);
113
114 RefMut(refmut, PhantomData, PhantomData)
115 }
116}
117
118pub enum Entry<'a, K, KB, VB, Marker>
119where
120 K: 'static + TypedMapKey<Marker>,
121 KB: 'static + Bounds + HasBounds<K>,
122 VB: 'static + Bounds + HasBounds<K::Value>,
123{
124 Occupied(OccupiedEntry<'a, K, KB, VB, Marker>),
125 Vacant(VacantEntry<'a, K, KB, VB, Marker>),
126}
127
128pub(crate) fn map_entry<Marker, K, KB, VB>(
129 entry: dashmap::mapref::entry::Entry<'_, TypedKey<KB>, TypedMapValue<VB>>,
130) -> Entry<'_, K, KB, VB, Marker>
131where
132 K: 'static + TypedMapKey<Marker>,
133 KB: 'static + Bounds + HasBounds<K>,
134 VB: 'static + Bounds + HasBounds<K::Value>,
135{
136 match entry {
137 dashmap::mapref::entry::Entry::Occupied(base) => Entry::Occupied(OccupiedEntry {
138 base,
139 _phantom: PhantomData,
140 _phantom_key: PhantomData,
141 }),
142 dashmap::mapref::entry::Entry::Vacant(base) => Entry::Vacant(VacantEntry {
143 base,
144 _phantom: PhantomData,
145 _phantom_key: PhantomData,
146 }),
147 }
148}
149
150impl<'a, Marker, K, KB, VB> Entry<'a, K, KB, VB, Marker>
151where
152 K: 'static + TypedMapKey<Marker>,
153 KB: 'static + Bounds + HasBounds<K>,
154 VB: 'static + Bounds + HasBounds<K::Value>,
155{
156 #[inline]
157 pub fn or_insert(self, default: K::Value) -> RefMut<'a, Marker, K, KB, VB> {
158 match self {
159 Self::Occupied(entry) => entry.into_ref(),
160 Self::Vacant(entry) => entry.insert(default),
161 }
162 }
163
164 #[inline]
165 pub fn or_insert_with<F: FnOnce() -> K::Value>(
166 self,
167 default: F,
168 ) -> RefMut<'a, Marker, K, KB, VB> {
169 match self {
170 Self::Occupied(entry) => entry.into_ref(),
171 Self::Vacant(entry) => entry.insert(default()),
172 }
173 }
174
175 pub fn key(&self) -> &K {
176 match *self {
177 Self::Occupied(ref entry) => entry.key(),
178 Self::Vacant(ref entry) => entry.key(),
179 }
180 }
181
182 pub fn and_modify<F>(self, f: F) -> Self
183 where
184 F: FnOnce(&mut K::Value),
185 {
186 match self {
187 Self::Occupied(mut entry) => {
188 f(entry.get_mut());
189 Self::Occupied(entry)
190 }
191 Self::Vacant(entry) => Self::Vacant(entry),
192 }
193 }
194}
195
196impl<'a, Marker, K, KB, VB> Entry<'a, K, KB, VB, Marker>
197where
198 K: 'static + TypedMapKey<Marker>,
199 K::Value: 'static + Default,
200 KB: 'static + Bounds + HasBounds<K>,
201 VB: 'static + Bounds + HasBounds<K::Value>,
202{
203 pub fn or_default(self) -> RefMut<'a, Marker, K, KB, VB> {
204 match self {
205 Self::Occupied(entry) => entry.into_ref(),
206 Self::Vacant(entry) => entry.insert(Default::default()),
207 }
208 }
209}