typedmap/
dashmap.rs

1//! Provides [`TypedDashMap`], a concurrent version of [TypedMap](crate::TypedMap)
2use std::collections::hash_map::RandomState;
3use std::fmt::Formatter;
4use std::hash::BuildHasher;
5use std::marker::PhantomData;
6use std::ops::Deref;
7use std::{fmt::Debug, ops::DerefMut};
8
9use dashmap::DashMap;
10
11use crate::bounds::{Bounds, HasBounds, SyncAnyBounds};
12use crate::dashentry;
13use crate::hashmap::TypedKeyValue;
14use crate::typedkey::{Key, TypedKey, TypedKeyRef};
15use crate::typedvalue::TypedMapValue;
16use crate::TypedMapKey;
17
18/// A concurrent hash map that can store keys of any type that implements [`TypedMapKey`] and values of
19/// type defined by [`TypedMapKey::Value`]. One can use Marker to define multiple "key-value" type
20/// mappings. Under the hood the [`DashMap`] is used. Note: that it will deadlock whenever DashMap will.
21///
22/// # Examples
23/// ```
24/// use std::sync::Arc;
25/// use typedmap::TypedDashMap;
26/// use typedmap::TypedMapKey;
27///
28/// struct Configs;
29/// struct Services;
30///
31/// #[derive(Hash, PartialEq, Eq)]
32/// struct ServiceA(usize);
33///
34/// // Implement key-value mapping for Configs marker
35/// impl TypedMapKey<Configs> for ServiceA {
36///     type Value = usize;
37/// }
38///
39/// // Implement key-value mapping for Services marker
40/// impl TypedMapKey<Services> for ServiceA {
41///     type Value = &'static str;
42/// }
43///
44/// #[derive(Hash, PartialEq, Eq)]
45/// struct ServiceB(&'static str);
46///
47/// // Implement key-value mapping for Configs marker
48/// impl TypedMapKey<Configs> for ServiceB {
49///     type Value = Vec<&'static str>;
50/// }
51///
52/// // Implement key-value mapping for Services marker
53/// impl TypedMapKey<Services> for ServiceB {
54///     type Value = usize;
55/// }
56///
57/// // Implement key-value mapping for default (i.e. ()) marker
58/// impl TypedMapKey for ServiceB {
59///     type Value = String;
60/// }
61///
62/// let configs: Arc<TypedDashMap<Configs>> = Arc::new(TypedDashMap::new());
63/// let services: Arc<TypedDashMap<Services>> = Arc::new(TypedDashMap::new());
64/// let default: Arc<TypedDashMap> = Arc::new(TypedDashMap::new());
65///
66/// let configs1 = Arc::clone(&configs);
67/// let services1 = Arc::clone(&services);
68/// let t1 = std::thread::spawn(move ||{
69///     configs1.insert(ServiceA(0), 1);
70///     services1.insert(ServiceA(0), "one");
71/// });
72/// // Line below would not compile, because TypeMapKey<Marker=()>
73/// // is not implemented for Key.
74/// // default.insert(Key(0), 1);
75///
76/// // Line below would not compile, because SerivceA key defines
77/// // type value as usize for Configs marker (not &'static str)
78/// // configs.insert(ServiceA(0), "one");
79///
80/// let configs2 = Arc::clone(&configs);
81/// let services2 = Arc::clone(&services);
82/// let default2 = Arc::clone(&default);
83/// let t2 = std::thread::spawn(move || {
84///     configs2.insert(ServiceB("zero"), vec!["one"]);
85///     services2.insert(ServiceB("zero"), 32);
86///     default2.insert(ServiceB("zero"), "one".to_owned());
87/// });
88///
89/// t1.join().unwrap();
90/// t2.join().unwrap();
91///
92/// assert_eq!(*configs.get(&ServiceB("zero")).unwrap(), vec!["one"]);
93/// assert_eq!(*services.get(&ServiceB("zero")).unwrap(), 32);
94/// assert_eq!(*default.get(&ServiceB("zero")).unwrap(), "one".to_owned());
95///
96/// ```
97pub struct TypedDashMap<
98    Marker = (),
99    KB: Bounds = SyncAnyBounds,
100    VB: Bounds = SyncAnyBounds,
101    S = RandomState,
102> {
103    state: DashMap<TypedKey<KB>, TypedMapValue<VB>, S>,
104    _phantom: PhantomData<Marker>,
105}
106
107const INVALID_KEY: &str = "Broken TypedDashMap: invalid key type";
108const INVALID_VALUE: &str = "Broken TypedDashMap: invalid value type";
109
110impl<Marker> TypedDashMap<Marker> {
111    /// Creates a new TypedDashMap with specified marker type.
112    ///
113    /// # Examples:
114    /// ```rust
115    /// use typedmap::TypedMap;
116    ///
117    /// struct Configs;
118    /// let map = TypedMap::<Configs>::new();
119    /// ```
120    pub fn new() -> Self {
121        TypedDashMap {
122            state: Default::default(),
123            _phantom: PhantomData,
124        }
125    }
126
127    /// Creates a new TypedDashMap with a specified capacity and specified marker type
128    pub fn with_capacity(capacity: usize) -> Self {
129        TypedDashMap {
130            state: DashMap::with_capacity(capacity),
131            _phantom: PhantomData,
132        }
133    }
134}
135
136impl<Marker, KB, VB> TypedDashMap<Marker, KB, VB>
137where
138    KB: 'static + Bounds,
139    VB: 'static + Bounds,
140{
141    pub fn new_with_bounds() -> Self {
142        TypedDashMap {
143            state: Default::default(),
144            _phantom: PhantomData,
145        }
146    }
147}
148
149impl<Marker, KB, VB, S> TypedDashMap<Marker, KB, VB, S>
150where
151    S: 'static + BuildHasher + Clone,
152    KB: 'static + Bounds,
153    VB: 'static + Bounds,
154{
155    /// Creates a new TypedDashMap with specified capacity, hasher and marker type.
156    pub fn with_capacity_and_hasher(capacity: usize, hash_builder: S) -> Self {
157        TypedDashMap {
158            state: DashMap::with_capacity_and_hasher(capacity, hash_builder),
159            _phantom: PhantomData,
160        }
161    }
162
163    /// Creates a new TypedDashMap with specified hasher and marker type.
164    pub fn with_hasher(hash_builder: S) -> Self {
165        TypedDashMap {
166            state: DashMap::with_hasher(hash_builder),
167            _phantom: PhantomData,
168        }
169    }
170
171    /// Inserts a key and a value into the map.
172    ///
173    /// If the map did not have this key present, None is returned.
174    ///
175    /// If the map did have this key present, the value is updated, and old value is returned.
176    ///
177    /// # Examples
178    /// ```
179    /// use typedmap::TypedDashMap;
180    /// use typedmap::TypedMapKey;
181    ///
182    /// #[derive(Debug, Hash, PartialEq, Eq)]
183    /// struct Key(usize);
184    ///
185    /// impl TypedMapKey for Key {
186    ///     type Value = usize;
187    /// }
188    ///
189    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
190    /// assert!(map.insert(Key(3), 4).is_none());
191    /// assert_eq!(map.insert(Key(3), 5), Some(4));
192    /// assert_eq!(*map.get(&Key(3)).unwrap(), 5);
193    /// ```
194    pub fn insert<K>(&self, key: K, value: K::Value) -> Option<K::Value>
195    where
196        K: 'static + TypedMapKey<Marker>,
197        KB: HasBounds<K>,
198        VB: HasBounds<K::Value>,
199    {
200        let typed_key = TypedKey::<KB>::from_key(key);
201        let value = TypedMapValue::<VB>::from_value(value);
202        let old_value = self.state.insert(typed_key, value)?;
203
204        Some(old_value.downcast::<K::Value>().expect(INVALID_VALUE))
205    }
206
207    /// Inserts a TypedKeyValue into the map from .
208    ///
209    /// If the map did not have this key present, None is returned.
210    ///
211    /// If the map did have this key present, the value is updated, and the old value is returned.
212    ///
213    /// # Examples
214    /// ```
215    /// use typedmap::hashmap::TypedKeyValue;
216    /// use typedmap::{TypedDashMap};
217    /// use typedmap::TypedMapKey;
218    ///
219    /// #[derive(Hash, PartialEq, Eq)]
220    /// struct Key(usize);
221    ///
222    /// impl TypedMapKey for Key {
223    ///     type Value = usize;
224    /// }
225    ///
226    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
227    /// let kv = TypedKeyValue::new(Key(3), 4);
228    /// map.insert_key_value(kv);
229    /// assert_eq!(*map.get(&Key(3)).unwrap().value(), 4);
230    /// ```
231    pub fn insert_key_value(
232        &mut self,
233        key_value: TypedKeyValue<Marker, KB, VB>,
234    ) -> Option<TypedKeyValue<Marker, KB, VB>> {
235        let entry = self.state.remove(&key_value.key);
236        self.state.insert(key_value.key, key_value.value);
237        let (key, value) = entry?;
238        Some(TypedKeyValue {
239            key,
240            value,
241            _marker: PhantomData,
242        })
243    }
244
245    /// Get the entry of a key if it exists in the map.
246    ///
247    /// # Examples
248    /// ```
249    /// use typedmap::TypedDashMap;
250    /// use typedmap::TypedMapKey;
251    ///
252    /// #[derive(Hash, PartialEq, Eq)]
253    /// struct Key(usize);
254    ///
255    /// impl TypedMapKey for Key {
256    ///     type Value = usize;
257    /// }
258    ///
259    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
260    /// assert!(map.get(&Key(3)).is_none());
261    /// map.insert(Key(3), 4);
262    /// assert_eq!(*map.get(&Key(3)).unwrap(), 4);
263    /// ```
264    pub fn get<K>(&self, key: &K) -> Option<Ref<'_, Marker, K, KB, VB>>
265    where
266        K: 'static + TypedMapKey<Marker>,
267        KB: HasBounds<K>,
268        VB: HasBounds<K::Value>,
269    {
270        let typed_key = TypedKeyRef::from_key_ref(key);
271        let value = self.state.get(&typed_key as &dyn Key)?;
272        Some(Ref(
273            value,
274            std::marker::PhantomData,
275            std::marker::PhantomData,
276        ))
277    }
278    /// Get mutable entry of a key if it exists in the map.
279    ///
280    /// # Examples
281    /// ```
282    /// use typedmap::TypedDashMap;
283    /// use typedmap::TypedMapKey;
284    ///
285    /// #[derive(Hash, PartialEq, Eq)]
286    /// struct Key(usize);
287    ///
288    /// impl TypedMapKey for Key {
289    ///     type Value = usize;
290    /// }
291    ///
292    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
293    /// assert!(map.get_mut(&Key(3)).is_none());
294    /// map.insert(Key(3), 4);
295    /// *map.get_mut(&Key(3)).unwrap() = 5;
296    /// assert_eq!(*map.get(&Key(3)).unwrap().value(), 5);
297    /// ```
298    pub fn get_mut<K>(&self, key: &K) -> Option<RefMut<'_, Marker, K, KB, VB>>
299    where
300        K: 'static + TypedMapKey<Marker>,
301        KB: HasBounds<K>,
302        VB: HasBounds<K::Value>,
303    {
304        let typed_key = TypedKeyRef::from_key_ref(key);
305        let value = self.state.get_mut(&typed_key as &dyn Key)?;
306        Some(RefMut(
307            value,
308            std::marker::PhantomData,
309            std::marker::PhantomData,
310        ))
311    }
312
313    /// Check if the map contains a specific key.
314    ///
315    /// # Examples
316    /// ```
317    /// use typedmap::TypedDashMap;
318    /// use typedmap::TypedMapKey;
319    ///
320    /// #[derive(Hash, PartialEq, Eq)]
321    /// struct Key(usize);
322    ///
323    /// impl TypedMapKey for Key {
324    ///     type Value = usize;
325    /// }
326    ///
327    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
328    /// assert!(!map.contains_key(&Key(3)));
329    /// map.insert(Key(3), 4);
330    /// assert!(map.contains_key(&Key(3)));
331    /// ```
332    pub fn contains_key<K>(&self, key: &K) -> bool
333    where
334        K: 'static + TypedMapKey<Marker>,
335        KB: HasBounds<K>,
336    {
337        let typed_key = TypedKeyRef::from_key_ref(key);
338        self.state.contains_key(&typed_key as &dyn Key)
339    }
340
341    /// Removes an entry from the map.
342    ///
343    /// Returns both key and value if the key existed and the entry was removed. Otherwise returns None.
344    ///
345    /// # Examples
346    /// ```
347    /// use typedmap::TypedDashMap;
348    /// use typedmap::TypedMapKey;
349    ///
350    /// #[derive(Debug, Hash, PartialEq, Eq)]
351    /// struct Key(usize);
352    ///
353    /// impl TypedMapKey for Key {
354    ///     type Value = usize;
355    /// }
356    ///
357    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
358    /// assert!(map.remove(&Key(3)).is_none());
359    /// map.insert(Key(3), 4);
360    /// assert!(map.contains_key(&Key(3)));
361    /// assert_eq!(map.remove(&Key(3)), Some((Key(3), 4)));
362    /// assert!(!map.contains_key(&Key(3)));
363    /// ```
364    pub fn remove<K>(&self, key: &K) -> Option<(K, K::Value)>
365    where
366        K: 'static + TypedMapKey<Marker>,
367        KB: HasBounds<K>,
368        VB: HasBounds<K::Value>,
369    {
370        let typed_key = TypedKeyRef::from_key_ref(key);
371        let (key, value) = self.state.remove(&typed_key as &dyn Key)?;
372        let key = key.downcast().expect(INVALID_KEY);
373        let value = value.downcast().expect(INVALID_VALUE);
374        Some((key, value))
375    }
376
377    /// Removes an entry from the map the provided conditional function returned true.
378    ///
379    /// Returns both key and value if the key existed and the entry was removed. Otherwise returns None.
380    ///
381    /// # Examples
382    /// ```
383    /// use typedmap::TypedDashMap;
384    /// use typedmap::TypedMapKey;
385    ///
386    /// #[derive(Debug, Hash, PartialEq, Eq)]
387    /// struct Key(usize);
388    ///
389    /// impl TypedMapKey for Key {
390    ///     type Value = usize;
391    /// }
392    ///
393    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
394    /// assert!(map.remove(&Key(3)).is_none());
395    /// map.insert(Key(3), 4);
396    /// assert!(map.contains_key(&Key(3)));
397    /// assert_eq!(map.remove_if(&Key(3), |k, v| false), None);
398    /// assert!(map.contains_key(&Key(3)));
399    /// assert_eq!(map.remove_if(&Key(3), |k, v| true), Some((Key(3), 4)));
400    /// assert!(!map.contains_key(&Key(3)));
401    /// ```
402    pub fn remove_if<K>(
403        &self,
404        key: &K,
405        f: impl FnOnce(&K, &K::Value) -> bool,
406    ) -> Option<(K, K::Value)>
407    where
408        K: 'static + TypedMapKey<Marker>,
409        KB: HasBounds<K>,
410        VB: HasBounds<K::Value>,
411    {
412        let typed_key = TypedKeyRef::from_key_ref(key);
413        let f = move |typed_key: &TypedKey<KB>, typed_value: &TypedMapValue<VB>| {
414            let k = typed_key.downcast_ref().expect(INVALID_KEY);
415            let v = typed_value.downcast_ref().expect(INVALID_VALUE);
416            f(k, v)
417        };
418        let (key, value) = self.state.remove_if(&typed_key as &dyn Key, f)?;
419        let key = key.downcast().expect(INVALID_KEY);
420        let value = value.downcast().expect(INVALID_VALUE);
421        Some((key, value))
422    }
423
424    /// Get the amount of entries in the map.
425    ///
426    /// # Examples
427    /// ```
428    /// use typedmap::TypedDashMap;
429    /// use typedmap::TypedMapKey;
430    ///
431    /// #[derive(Hash, PartialEq, Eq, Debug)]
432    /// struct Key(usize);
433    ///
434    /// impl TypedMapKey for Key {
435    ///     type Value = usize;
436    /// }
437    ///
438    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
439    /// assert_eq!(map.len(), 0);
440    /// map.insert(Key(3), 4);
441    /// assert_eq!(map.len(), 1);
442    /// ```
443    pub fn len(&self) -> usize {
444        self.state.len()
445    }
446
447    /// Returns true if the map contains no elements.
448    ///
449    /// # Examples
450    /// ```
451    /// use typedmap::TypedDashMap;
452    /// use typedmap::TypedMapKey;
453    ///
454    /// #[derive(Hash, PartialEq, Eq)]
455    /// struct Key(usize);
456    ///
457    /// impl TypedMapKey for Key {
458    ///     type Value = f32;
459    /// }
460    ///
461    /// let mut map: TypedDashMap = TypedDashMap::with_capacity(10);
462    /// assert!(map.is_empty());
463    /// map.insert(Key(3), 4.0);
464    /// assert!(!map.is_empty());
465    /// ```
466    pub fn is_empty(&self) -> bool {
467        self.state.is_empty()
468    }
469
470    /// Clears the map, removing all key-value pairs.
471    ///
472    /// # Examples:
473    /// ```
474    /// use typedmap::TypedDashMap;
475    /// use typedmap::TypedMapKey;
476    ///
477    /// #[derive(Hash, PartialEq, Eq)]
478    /// struct Key(usize);
479    ///
480    /// impl TypedMapKey for Key {
481    ///     type Value = f32;
482    /// }
483    ///
484    /// let mut map: TypedDashMap = TypedDashMap::new();
485    /// map.insert(Key(3), 4.0);
486    /// map.clear();
487    /// assert!(map.get(&Key(3)).is_none())
488    /// // assert!(map.is_empty()); // for some reason this fails
489    /// ```
490    pub fn clear(&self) {
491        self.state.clear();
492    }
493
494    /// An iterator visiting all key-value pairs in arbitrary order.
495    ///
496    /// # Examples
497    /// ```
498    /// use typedmap::TypedDashMap;
499    /// use typedmap::TypedMapKey;
500    ///
501    /// #[derive(Hash, PartialEq, Eq, Debug)]
502    /// struct Key(usize);
503    /// #[derive(Hash, PartialEq, Eq, Debug)]
504    /// struct SKey(&'static str);
505    ///
506    /// impl TypedMapKey for Key {
507    ///     type Value = u32;
508    /// }
509    ///
510    /// impl TypedMapKey for SKey {
511    ///     type Value = usize;
512    /// }
513    ///
514    /// let mut map: TypedDashMap = TypedDashMap::new();
515    /// map.insert(Key(3), 3);
516    /// map.insert(SKey("four"), 4);
517    ///
518    /// for key_value in map.iter() {
519    ///     if let Some((key, value)) = key_value.downcast_pair_ref::<Key>() {
520    ///         assert_eq!(key, &Key(3));
521    ///         assert_eq!(value, &3u32);
522    ///     }
523    ///
524    ///     if let Some((key, value)) = key_value.downcast_pair_ref::<SKey>() {
525    ///         assert_eq!(key, &SKey("four"));
526    ///         assert_eq!(value, &4);
527    ///     }
528    /// }
529    /// ```
530    pub fn iter(&self) -> Iter<'_, Marker, KB, VB, S> {
531        Iter(self.state.iter(), PhantomData)
532    }
533
534    /// An iterator visiting all key-value pairs in arbitrary order yielding mutable references.
535    ///
536    /// # Examples
537    /// ```
538    /// use typedmap::TypedDashMap;
539    /// use typedmap::TypedMapKey;
540    ///
541    /// #[derive(Hash, PartialEq, Eq, Debug)]
542    /// struct Key(usize);
543    /// #[derive(Hash, PartialEq, Eq, Debug)]
544    /// struct SKey(&'static str);
545    ///
546    /// impl TypedMapKey for Key {
547    ///     type Value = u32;
548    /// }
549    ///
550    /// impl TypedMapKey for SKey {
551    ///     type Value = usize;
552    /// }
553    ///
554    /// let mut map: TypedDashMap = TypedDashMap::new();
555    /// map.insert(Key(3), 3);
556    /// map.insert(SKey("four"), 4);
557    ///
558    /// for mut key_value in map.iter_mut() {
559    ///     if let Some((key, value)) = key_value.downcast_pair_mut::<Key>() {
560    ///         assert_eq!(key, &Key(3));
561    ///         assert_eq!(value, &3u32);
562    ///         *value = 4u32;
563    ///     }
564    ///
565    ///     if let Some((key, value)) = key_value.downcast_pair_mut::<SKey>() {
566    ///         assert_eq!(key, &SKey("four"));
567    ///         assert_eq!(value, &4);
568    ///     }
569    /// }
570    /// ```
571    pub fn iter_mut(&self) -> IterMut<'_, Marker, KB, VB, S> {
572        IterMut(self.state.iter_mut(), PhantomData)
573    }
574
575    /// Gets the given key's corresponding entry in the map for in-place manipulation.
576    ///
577    /// # Examples
578    /// ```
579    /// use typedmap::TypedDashMap;
580    /// use typedmap::TypedMapKey;
581    ///
582    /// #[derive(Hash, PartialEq, Eq)]
583    /// struct Key(char);
584    ///
585    /// impl TypedMapKey for Key {
586    ///     type Value = usize;
587    /// }
588    ///
589    /// let letters: TypedDashMap = TypedDashMap::new();
590    /// for ch in "a short treatise on fungi".chars() {
591    ///    let mut counter = letters.entry(Key(ch)).or_insert(0);
592    ///    *counter += 1;
593    /// }
594    /// assert_eq!(letters.get(&Key('s')).unwrap().value(), &2);
595    /// assert_eq!(letters.get(&Key('t')).unwrap().value(), &3);
596    /// assert_eq!(letters.get(&Key('u')).unwrap().value(), &1);
597    /// assert!(letters.get(&Key('y')).is_none());
598    /// ```
599    pub fn entry<K>(&self, key: K) -> dashentry::Entry<'_, K, KB, VB, Marker>
600    where
601        K: 'static + TypedMapKey<Marker>,
602        KB: HasBounds<K>,
603        VB: HasBounds<K::Value>,
604    {
605        let typed_key = TypedKey::from_key(key);
606        dashentry::map_entry(self.state.entry(typed_key))
607    }
608
609    /// Retain elements that the filter closure returns true for.
610    ///
611    /// # Examples
612    /// ```
613    /// use typedmap::TypedDashMap;
614    /// use typedmap::TypedMapKey;
615    ///
616    /// #[derive(Hash, PartialEq, Eq, Debug)]
617    /// struct Key(usize);
618    /// #[derive(Hash, PartialEq, Eq, Debug)]
619    /// struct SKey(&'static str);
620    ///
621    /// impl TypedMapKey for Key {
622    ///     type Value = u32;
623    /// }
624    ///
625    /// impl TypedMapKey for SKey {
626    ///     type Value = usize;
627    /// }
628    ///
629    /// let mut map: TypedDashMap = TypedDashMap::new();
630    /// map.insert(Key(3), 3);
631    /// map.insert(SKey("four"), 4);
632    ///
633    /// map.retain(|kv| kv.downcast_key_ref::<Key>().is_some());
634    /// assert!(map.contains_key(&Key(3)));
635    /// ```
636    pub fn retain(&self, mut predicate: impl FnMut(TypedKeyValueRef<Marker, KB, VB>) -> bool) {
637        let ff = move |key: &TypedKey<KB>, value: &mut TypedMapValue<VB>| {
638            let kv = TypedKeyValueRef {
639                key,
640                value,
641                _marker: PhantomData,
642            };
643            predicate(kv)
644        };
645        self.state.retain(ff);
646    }
647}
648
649impl<Marker> Default for TypedDashMap<Marker> {
650    fn default() -> Self {
651        TypedDashMap::new()
652    }
653}
654
655impl<Marker, KB, VB, S> Debug for TypedDashMap<Marker, KB, VB, S>
656where
657    KB: 'static + Bounds,
658    VB: 'static + Bounds,
659{
660    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
661        f.write_str("TypedDashMap:40")
662    }
663}
664
665/// An iterator over the entries of a TypedDashMap
666///
667/// This `struct` is created by ['iter'] method on [`TypedDashMap`]. See its documentation for more.
668///
669/// ['iter']: crate::TypedMap::iter
670///
671/// # Example
672/// ```
673/// use typedmap::TypedDashMap;
674/// use typedmap::TypedMapKey;
675///
676/// #[derive(Hash, PartialEq, Eq, Debug)]
677/// struct Key(usize);
678///
679/// impl TypedMapKey for Key {
680///     type Value = u32;
681/// }
682///
683/// let mut map: TypedDashMap = TypedDashMap::new();
684/// map.insert(Key(3), 3);
685/// let iter = map.iter();
686///
687pub struct Iter<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds, S>(
688    dashmap::iter::Iter<'a, TypedKey<KB>, TypedMapValue<VB>, S>,
689    PhantomData<Marker>,
690);
691
692impl<'a, Marker, KB, VB, S> Iterator for Iter<'a, Marker, KB, VB, S>
693where
694    KB: 'static + Bounds,
695    VB: 'static + Bounds,
696    S: BuildHasher + Clone,
697{
698    type Item = TypedKeyValueGuard<'a, Marker, KB, VB>;
699
700    fn next(&mut self) -> Option<Self::Item> {
701        let key_value = self.0.next()?;
702        Some(TypedKeyValueGuard {
703            key_value,
704            _marker: PhantomData,
705        })
706    }
707}
708
709pub struct TypedKeyValueGuard<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> {
710    key_value: dashmap::mapref::multiple::RefMulti<'a, TypedKey<KB>, TypedMapValue<VB>>,
711    _marker: PhantomData<Marker>,
712}
713
714impl<Marker, KB, VB> TypedKeyValueGuard<'_, Marker, KB, VB>
715where
716    KB: 'static + Bounds,
717    VB: 'static + Bounds,
718{
719    /// Downcast key to reference of `K`. Returns `None` if not possible.
720    pub fn downcast_key_ref<K: 'static + TypedMapKey<Marker>>(&self) -> Option<&'_ K>
721    where
722        KB: HasBounds<K>,
723    {
724        self.key_value.key().downcast_ref()
725    }
726
727    /// Downcast value and returns reference or `None` if downcast failed.
728    pub fn downcast_value_ref<V: 'static>(&self) -> Option<&'_ V>
729    where
730        VB: HasBounds<V>,
731    {
732        self.key_value.value().downcast_ref()
733    }
734
735    /// Downcast key to reference of `K` and value to reference of `K::Value`.
736    /// Returns `None` if not possible.
737    pub fn downcast_pair_ref<K>(&self) -> Option<(&'_ K, &'_ K::Value)>
738    where
739        K: 'static + TypedMapKey<Marker>,
740        KB: HasBounds<K>,
741        VB: HasBounds<K::Value>,
742    {
743        let (key, value) = self.key_value.pair();
744        Some((key.downcast_ref()?, value.downcast_ref()?))
745    }
746
747    pub fn key_container_ref(&self) -> &KB::Container {
748        self.key_value.key().as_container()
749    }
750
751    pub fn value_container_ref(&self) -> &VB::Container {
752        self.key_value.value().as_container()
753    }
754}
755
756#[cfg(feature = "clone")]
757impl<M, KB: Bounds, VB: Bounds> TypedKeyValueGuard<'_, M, KB, VB>
758where
759    KB::KeyContainer: crate::clone::CloneAny,
760    VB::Container: crate::clone::CloneAny,
761{
762    /// Turns borrowed key/value pair into owned [TypedKeyValue](crate::hashmap::TypedKeyValue) by cloning key & value.
763    ///
764    /// ```rust
765    /// use typedmap::{TypedDashMap, TypedMap};use typedmap::clone::SyncCloneBounds;
766    /// use typedmap::TypedMapKey;
767    ///
768    /// #[derive(Hash, PartialEq, Eq, Debug, Clone)]
769    /// struct Key(usize);
770    ///
771    /// impl TypedMapKey for Key {
772    ///     type Value = u32;
773    /// }
774    ///
775    /// let map: TypedDashMap<(), SyncCloneBounds, SyncCloneBounds> = TypedDashMap::new_with_bounds();
776    /// map.insert(Key(3), 3);
777    ///
778    /// let mut new_map: TypedMap<(), SyncCloneBounds, SyncCloneBounds> = TypedMap::new_with_bounds();
779    /// for entry in map.iter() {
780    ///     new_map.insert_key_value(entry.to_owned());
781    /// }
782    /// ```
783    pub fn to_owned(&self) -> TypedKeyValue<M, KB, VB> {
784        let key = crate::clone::clone_box(&*self.key_value.key().0);
785        let value = crate::clone::clone_box(self.key_value.value().as_container());
786        TypedKeyValue {
787            key: TypedKey(key),
788            value: TypedMapValue(value),
789            _marker: self._marker,
790        }
791    }
792}
793
794impl<M, KB: Bounds, VB: Bounds, S: BuildHasher + Clone + Default>
795    FromIterator<TypedKeyValue<M, KB, VB>> for TypedDashMap<M, KB, VB, S>
796{
797    fn from_iter<T: IntoIterator<Item = TypedKeyValue<M, KB, VB>>>(iter: T) -> Self {
798        let state = iter.into_iter().map(|i| (i.key, i.value)).collect();
799        TypedDashMap {
800            state,
801            _phantom: PhantomData,
802        }
803    }
804}
805
806/// An iterator over the entries of a TypedDashMap yielding mutable references
807///
808/// This `struct` is created by ['iter_mut'] method on [`TypedDashMap`]. See its documentation for more.
809///
810/// ['iter']: crate::TypedMap::iter
811///
812/// # Example
813/// ```
814/// use typedmap::TypedDashMap;
815/// use typedmap::TypedMapKey;
816///
817/// #[derive(Hash, PartialEq, Eq, Debug)]
818/// struct Key(usize);
819///
820/// impl TypedMapKey for Key {
821///     type Value = u32;
822/// }
823///
824/// let mut map: TypedDashMap = TypedDashMap::new();
825/// map.insert(Key(3), 3);
826/// let iter = map.iter_mut();
827///
828pub struct IterMut<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds, S>(
829    dashmap::iter::IterMut<'a, TypedKey<KB>, TypedMapValue<VB>, S>,
830    PhantomData<Marker>,
831);
832
833impl<'a, Marker, KB, VB, S> Iterator for IterMut<'a, Marker, KB, VB, S>
834where
835    KB: 'static + Bounds,
836    VB: 'static + Bounds,
837    S: BuildHasher + Clone,
838{
839    type Item = TypedKeyValueMutGuard<'a, Marker, KB, VB>;
840
841    fn next(&mut self) -> Option<Self::Item> {
842        let key_value = self.0.next()?;
843        Some(TypedKeyValueMutGuard {
844            key_value,
845            _marker: PhantomData,
846        })
847    }
848}
849
850pub struct TypedKeyValueMutGuard<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> {
851    key_value: dashmap::mapref::multiple::RefMutMulti<'a, TypedKey<KB>, TypedMapValue<VB>>,
852    _marker: PhantomData<Marker>,
853}
854
855impl<Marker, KB, VB> TypedKeyValueMutGuard<'_, Marker, KB, VB>
856where
857    KB: 'static + Bounds,
858    VB: 'static + Bounds,
859{
860    /// Downcast key to reference of `K`. Returns `None` if not possible.
861    pub fn downcast_key_ref<K: 'static + TypedMapKey<Marker>>(&self) -> Option<&'_ K>
862    where
863        KB: HasBounds<K>,
864    {
865        self.key_value.key().downcast_ref()
866    }
867
868    /// Downcast value and returns reference or `None` if downcast failed.
869    pub fn downcast_value_ref<V: 'static>(&self) -> Option<&'_ V>
870    where
871        VB: HasBounds<V>,
872    {
873        self.key_value.value().downcast_ref()
874    }
875
876    /// Downcast value and returns reference or `None` if downcast failed.
877    pub fn downcast_value_mut<V: 'static>(&mut self) -> Option<&'_ mut V>
878    where
879        VB: HasBounds<V>,
880    {
881        self.key_value.value_mut().downcast_mut()
882    }
883
884    /// Downcast key to reference of `K` and value to reference of `K::Value`.
885    /// Returns `None` if not possible.
886    pub fn downcast_pair_ref<K>(&self) -> Option<(&'_ K, &'_ K::Value)>
887    where
888        K: 'static + TypedMapKey<Marker>,
889        KB: HasBounds<K>,
890        VB: HasBounds<K::Value>,
891    {
892        let (key, value) = self.key_value.pair();
893        Some((key.downcast_ref()?, value.downcast_ref()?))
894    }
895
896    /// Downcast key to reference of `K` and value to reference of `K::Value`.
897    /// Returns `None` if not possible.
898    pub fn downcast_pair_mut<K>(&mut self) -> Option<(&'_ K, &'_ mut K::Value)>
899    where
900        K: 'static + TypedMapKey<Marker>,
901        KB: HasBounds<K>,
902        VB: HasBounds<K::Value>,
903    {
904        let (key, value) = self.key_value.pair_mut();
905        Some((key.downcast_ref()?, value.downcast_mut()?))
906    }
907
908    pub fn key_container_ref(&self) -> &KB::Container {
909        self.key_value.key().as_container()
910    }
911
912    pub fn value_container_ref(&self) -> &VB::Container {
913        self.key_value.value().as_container()
914    }
915
916    pub fn value_container_mut(&mut self) -> &mut VB::Container {
917        self.key_value.value_mut().as_mut_container()
918    }
919}
920
921#[cfg(feature = "clone")]
922impl<M, KB: Bounds, VB: Bounds> TypedKeyValueMutGuard<'_, M, KB, VB>
923where
924    KB::KeyContainer: crate::clone::CloneAny,
925    VB::Container: crate::clone::CloneAny,
926{
927    /// Turns borrowed key/value pair into owned [TypedKeyValue](crate::hashmap::TypedKeyValue) by cloning key & value.
928    ///
929    /// ```rust
930    /// use typedmap::{TypedDashMap, TypedMap};use typedmap::clone::SyncCloneBounds;
931    /// use typedmap::TypedMapKey;
932    ///
933    /// #[derive(Hash, PartialEq, Eq, Debug, Clone)]
934    /// struct Key(usize);
935    ///
936    /// impl TypedMapKey for Key {
937    ///     type Value = u32;
938    /// }
939    ///
940    /// let map: TypedDashMap<(), SyncCloneBounds, SyncCloneBounds> = TypedDashMap::new_with_bounds();
941    /// map.insert(Key(3), 3);
942    ///
943    /// let mut new_map: TypedMap<(), SyncCloneBounds, SyncCloneBounds> = TypedMap::new_with_bounds();
944    /// for entry in map.iter_mut() {
945    ///     new_map.insert_key_value(entry.to_owned());
946    /// }
947    /// ```
948    pub fn to_owned(&self) -> TypedKeyValue<M, KB, VB> {
949        let key = crate::clone::clone_box(&*self.key_value.key().0);
950        let value = crate::clone::clone_box(self.key_value.value().as_container());
951        TypedKeyValue {
952            key: TypedKey(key),
953            value: TypedMapValue(value),
954            _marker: self._marker,
955        }
956    }
957}
958
959/// An immutable reference
960pub struct Ref<'a, Marker, K, KB, VB>(
961    dashmap::mapref::one::Ref<'a, TypedKey<KB>, TypedMapValue<VB>>,
962    std::marker::PhantomData<K>,
963    std::marker::PhantomData<Marker>,
964)
965where
966    K: 'static + TypedMapKey<Marker>,
967    KB: 'static + Bounds + HasBounds<K>,
968    VB: 'static + Bounds + HasBounds<K::Value>;
969
970impl<Marker, K, KB, VB> Ref<'_, Marker, K, KB, VB>
971where
972    K: 'static + TypedMapKey<Marker>,
973    KB: 'static + Bounds + HasBounds<K>,
974    VB: 'static + Bounds + HasBounds<K::Value>,
975{
976    pub fn key(&self) -> &K {
977        self.0.key().downcast_ref::<K>().expect(INVALID_KEY)
978    }
979
980    pub fn value(&self) -> &K::Value {
981        self.0
982            .value()
983            .downcast_ref::<K::Value>()
984            .expect(INVALID_VALUE)
985    }
986
987    pub fn pair(&self) -> (&K, &K::Value) {
988        (self.key(), self.value())
989    }
990}
991
992impl<Marker, K, KB, VB> Deref for Ref<'_, Marker, K, KB, VB>
993where
994    K: 'static + TypedMapKey<Marker>,
995    KB: 'static + Bounds + HasBounds<K>,
996    VB: 'static + Bounds + HasBounds<K::Value>,
997{
998    type Target = K::Value;
999
1000    fn deref(&self) -> &K::Value {
1001        self.value()
1002    }
1003}
1004
1005impl<Marker, K, KB, VB> Debug for Ref<'_, Marker, K, KB, VB>
1006where
1007    K: 'static + TypedMapKey<Marker>,
1008    KB: 'static + Bounds + HasBounds<K>,
1009    VB: 'static + Bounds + HasBounds<K::Value>,
1010{
1011    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
1012        f.write_str("Ref")
1013    }
1014}
1015
1016/// A mutable reference
1017pub struct RefMut<'a, Marker, K, KB, VB>(
1018    pub(crate) dashmap::mapref::one::RefMut<'a, TypedKey<KB>, TypedMapValue<VB>>,
1019    pub(crate) PhantomData<K>,
1020    pub(crate) PhantomData<Marker>,
1021)
1022where
1023    K: 'static + TypedMapKey<Marker>,
1024    KB: 'static + Bounds + HasBounds<K>,
1025    VB: 'static + Bounds + HasBounds<K::Value>;
1026
1027impl<Marker, K, KB, VB> RefMut<'_, Marker, K, KB, VB>
1028where
1029    K: 'static + TypedMapKey<Marker>,
1030    KB: 'static + Bounds + HasBounds<K>,
1031    VB: 'static + Bounds + HasBounds<K::Value>,
1032{
1033    pub fn key(&self) -> &K {
1034        self.0.key().downcast_ref::<K>().expect(INVALID_KEY)
1035    }
1036
1037    pub fn value(&self) -> &K::Value {
1038        self.0
1039            .value()
1040            .downcast_ref::<K::Value>()
1041            .expect(INVALID_VALUE)
1042    }
1043
1044    pub fn value_mut(&mut self) -> &mut K::Value {
1045        self.0
1046            .value_mut()
1047            .downcast_mut::<K::Value>()
1048            .expect(INVALID_VALUE)
1049    }
1050
1051    pub fn pair(&self) -> (&K, &K::Value) {
1052        (self.key(), self.value())
1053    }
1054
1055    pub fn pair_mut(&mut self) -> (&K, &K::Value) {
1056        let (key, value) = self.0.pair_mut();
1057        let key = key.downcast_ref::<K>().expect(INVALID_KEY);
1058        let value = value.downcast_mut::<K::Value>().expect(INVALID_VALUE);
1059        (key, value)
1060    }
1061}
1062
1063impl<Marker, K, KB, VB> Deref for RefMut<'_, Marker, K, KB, VB>
1064where
1065    K: 'static + TypedMapKey<Marker>,
1066    KB: 'static + Bounds + HasBounds<K>,
1067    VB: 'static + Bounds + HasBounds<K::Value>,
1068{
1069    type Target = K::Value;
1070
1071    fn deref(&self) -> &K::Value {
1072        self.value()
1073    }
1074}
1075
1076impl<Marker, K, KB, VB> DerefMut for RefMut<'_, Marker, K, KB, VB>
1077where
1078    K: 'static + TypedMapKey<Marker>,
1079    KB: 'static + Bounds + HasBounds<K>,
1080    VB: 'static + Bounds + HasBounds<K::Value>,
1081{
1082    fn deref_mut(&mut self) -> &mut Self::Target {
1083        self.value_mut()
1084    }
1085}
1086
1087impl<Marker, K, KB, VB> Debug for RefMut<'_, Marker, K, KB, VB>
1088where
1089    K: 'static + TypedMapKey<Marker>,
1090    KB: 'static + Bounds + HasBounds<K>,
1091    VB: 'static + Bounds + HasBounds<K::Value>,
1092{
1093    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error> {
1094        f.write_str("RefMut")
1095    }
1096}
1097
1098/// Represents borrowed pair of key and value.
1099pub struct TypedKeyValueRef<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> {
1100    key: &'a TypedKey<KB>,
1101    value: &'a TypedMapValue<VB>,
1102    _marker: PhantomData<Marker>,
1103}
1104
1105impl<'a, Marker, KB: 'static + Bounds, VB: 'static + Bounds> TypedKeyValueRef<'a, Marker, KB, VB> {
1106    /// Downcast key to reference of `K`. Returns `None` if not possible.
1107    pub fn downcast_key_ref<K: 'static + TypedMapKey<Marker>>(&self) -> Option<&'a K>
1108    where
1109        KB: HasBounds<K>,
1110    {
1111        self.key.downcast_ref()
1112    }
1113
1114    /// Downcast value and returns reference or `None` if downcast failed.
1115    pub fn downcast_value_ref<V: 'static>(&self) -> Option<&'a V>
1116    where
1117        VB: HasBounds<V>,
1118    {
1119        self.value.downcast_ref()
1120    }
1121
1122    /// Downcast key to reference of `K` and value to reference of `K::Value`.
1123    /// Returns `None` if not possible.
1124    pub fn downcast_pair_ref<K>(&self) -> Option<(&'a K, &'a K::Value)>
1125    where
1126        K: 'static + TypedMapKey<Marker>,
1127        KB: HasBounds<K>,
1128        VB: HasBounds<K::Value>,
1129    {
1130        self.downcast_key_ref()
1131            .and_then(move |key| self.downcast_value_ref().map(move |value| (key, value)))
1132    }
1133
1134    pub fn key_container_ref(&self) -> &KB::Container {
1135        self.key.as_container()
1136    }
1137
1138    pub fn value_container_ref(&self) -> &VB::Container {
1139        self.value.as_container()
1140    }
1141}
1142
1143#[cfg(test)]
1144mod tests {
1145    use std::hash::Hash;
1146    use std::sync::Arc;
1147
1148    use crate::TypedMapKey;
1149    use crate::{SyncAnyBounds, TypedDashMap, TypedMap};
1150
1151    struct M;
1152    impl TypedMapKey<M> for String {
1153        type Value = String;
1154    }
1155
1156    #[test]
1157    fn test_threads() {
1158        let map: Arc<TypedDashMap> = Arc::new(TypedDashMap::new());
1159
1160        #[derive(Debug, Hash, PartialEq, Eq)]
1161        struct Key(String);
1162
1163        impl TypedMapKey for Key {
1164            type Value = String;
1165        }
1166
1167        let map1 = map.clone();
1168        let th1 = std::thread::spawn(move || {
1169            map1.insert(Key("k1".to_owned()), "v1".to_owned());
1170        });
1171
1172        let map2 = map.clone();
1173        let th2 = std::thread::spawn(move || {
1174            map2.insert(Key("k2".to_owned()), "v2".to_owned());
1175        });
1176
1177        th1.join().unwrap();
1178        th2.join().unwrap();
1179
1180        let k1 = Key("k1".to_owned());
1181        let k2 = Key("k2".to_owned());
1182
1183        let r = map.get(&k1).unwrap();
1184        assert_eq!(r.key(), &k1);
1185        assert_eq!(r.value(), &"v1".to_owned());
1186
1187        let r = map.get(&k2).unwrap();
1188        assert_eq!(r.pair(), (&k2, &"v2".to_owned()));
1189    }
1190
1191    #[test]
1192    fn test_from_iterator() {
1193        let mut state: TypedMap<M, SyncAnyBounds, SyncAnyBounds> = TypedMap::new_with_bounds();
1194        state.insert("key".to_owned(), "value".to_owned());
1195
1196        let new_map: TypedDashMap<M> = state.into_iter().collect();
1197
1198        assert_eq!(
1199            new_map.get(&"key".to_owned()).unwrap().value(),
1200            &"value".to_owned()
1201        );
1202    }
1203}