weak_map/
traits.rs

1use alloc::{rc, sync};
2
3/// A trait for strong references.
4pub trait StrongRef {
5    /// The type of the weak reference.
6    ///
7    /// For example, for `std::rc::Rc<T>`, this will be `std::rc::Weak<T>`.
8    type Weak: WeakRef<Strong = Self>;
9
10    /// Constructs a weak reference from a strong reference.
11    ///
12    /// This is usually implemented by a `downgrade` method.
13    fn downgrade(&self) -> Self::Weak;
14
15    /// Compare two strong references for equality.
16    ///
17    /// This is usually implemented by a `ptr_eq` method.
18    fn ptr_eq(&self, other: &Self) -> bool;
19}
20
21/// A trait for weak references.
22pub trait WeakRef {
23    /// The type of the strong reference.
24    ///
25    /// For example, for `std::rc::Weak<T>`, this will be `std::rc::Rc<T>`.
26    type Strong: StrongRef<Weak = Self>;
27
28    /// Acquires a strong reference from a weak reference.
29    ///
30    /// This is usually implemented by an `upgrade` method.
31    fn upgrade(&self) -> Option<Self::Strong>;
32
33    /// Is the given weak element expired?
34    ///
35    /// The default implemention checks whether a strong reference can be
36    /// obtained via `upgrade`.
37    fn is_expired(&self) -> bool {
38        self.upgrade().is_none()
39    }
40}
41
42impl<T: ?Sized> StrongRef for rc::Rc<T> {
43    type Weak = rc::Weak<T>;
44
45    fn downgrade(&self) -> Self::Weak {
46        rc::Rc::downgrade(self)
47    }
48
49    fn ptr_eq(&self, other: &Self) -> bool {
50        rc::Rc::ptr_eq(self, other)
51    }
52}
53
54impl<T: ?Sized> WeakRef for rc::Weak<T> {
55    type Strong = rc::Rc<T>;
56
57    fn upgrade(&self) -> Option<Self::Strong> {
58        self.upgrade()
59    }
60
61    fn is_expired(&self) -> bool {
62        self.strong_count() == 0
63    }
64}
65
66impl<T: ?Sized> StrongRef for sync::Arc<T> {
67    type Weak = sync::Weak<T>;
68
69    fn downgrade(&self) -> Self::Weak {
70        sync::Arc::downgrade(self)
71    }
72
73    fn ptr_eq(&self, other: &Self) -> bool {
74        sync::Arc::ptr_eq(self, other)
75    }
76}
77
78impl<T: ?Sized> WeakRef for sync::Weak<T> {
79    type Strong = sync::Arc<T>;
80
81    fn upgrade(&self) -> Option<Self::Strong> {
82        self.upgrade()
83    }
84
85    fn is_expired(&self) -> bool {
86        self.strong_count() == 0
87    }
88}