1use fuchsia_rcu::RcuDroppable;
6use ref_cast::RefCast;
7use std::borrow::Borrow;
8use std::cmp::Ordering;
9use std::hash::{Hash, Hasher};
10use std::ops::Deref;
11use std::sync::{Arc, Weak};
12
13#[derive(RefCast, RcuDroppable)]
15#[repr(transparent)]
16pub struct ArcKey<T>(pub Arc<T>);
17impl<T> PartialEq for ArcKey<T> {
18 fn eq(&self, other: &Self) -> bool {
19 Arc::ptr_eq(&self.0, &other.0)
20 }
21}
22impl<T> Eq for ArcKey<T> {}
23impl<T> PartialOrd for ArcKey<T> {
24 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
25 Some(self.cmp(other))
26 }
27}
28impl<T> Ord for ArcKey<T> {
29 fn cmp(&self, other: &Self) -> Ordering {
30 Arc::as_ptr(&self.0).cmp(&Arc::as_ptr(&other.0))
31 }
32}
33impl<T> Hash for ArcKey<T> {
34 fn hash<H: Hasher>(&self, state: &mut H) {
35 Arc::as_ptr(&self.0).hash(state);
36 }
37}
38impl<T> Clone for ArcKey<T> {
39 fn clone(&self) -> Self {
40 Self(Arc::clone(&self.0))
41 }
42}
43impl<T> Deref for ArcKey<T> {
44 type Target = Arc<T>;
45 fn deref(&self) -> &Self::Target {
46 &self.0
47 }
48}
49
50impl<T: std::fmt::Debug> std::fmt::Debug for ArcKey<T> {
51 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
52 self.0.fmt(f)
53 }
54}
55
56pub struct WeakKey<T>(pub Weak<T>, PtrKey<T>);
58impl<T> WeakKey<T> {
59 pub fn from(arc: &Arc<T>) -> Self {
60 Self(Arc::downgrade(arc), Arc::as_ptr(arc).into())
61 }
62}
63impl<T> Clone for WeakKey<T> {
64 fn clone(&self) -> Self {
65 Self(self.0.clone(), self.1.clone())
66 }
67}
68impl<T> PartialEq<Weak<T>> for WeakKey<T> {
69 fn eq(&self, other: &Weak<T>) -> bool {
70 Weak::ptr_eq(&self.0, other)
71 }
72}
73impl<T> PartialEq for WeakKey<T> {
74 fn eq(&self, other: &Self) -> bool {
75 *self == other.0
76 }
77}
78impl<T> Eq for WeakKey<T> {}
79impl<T> PartialOrd for WeakKey<T> {
80 fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
81 Some(self.cmp(other))
82 }
83}
84impl<T> Ord for WeakKey<T> {
85 fn cmp(&self, other: &Self) -> Ordering {
86 Weak::as_ptr(&self.0).cmp(&Weak::as_ptr(&other.0))
87 }
88}
89impl<T> Hash for WeakKey<T> {
90 fn hash<H: Hasher>(&self, state: &mut H) {
91 Weak::as_ptr(&self.0).hash(state);
92 }
93}
94impl<T> Borrow<PtrKey<T>> for WeakKey<T> {
95 fn borrow(&self) -> &PtrKey<T> {
96 &self.1
97 }
98}
99
100impl<T: std::fmt::Debug> std::fmt::Debug for WeakKey<T> {
101 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
102 self.0.fmt(f)
103 }
104}
105
106pub struct PtrKey<T>(*const T);
107impl<T> From<*const T> for PtrKey<T> {
108 fn from(ptr: *const T) -> Self {
109 Self(ptr)
110 }
111}
112impl<T> From<&T> for PtrKey<T> {
113 fn from(r: &T) -> Self {
114 Self(r as *const T)
115 }
116}
117impl<T> From<&Arc<T>> for PtrKey<T> {
118 fn from(arc: &Arc<T>) -> Self {
119 Self(Arc::as_ptr(arc))
120 }
121}
122impl<T> From<&ArcKey<T>> for PtrKey<T> {
123 fn from(arc_key: &ArcKey<T>) -> Self {
124 Self(Arc::as_ptr(&arc_key.0))
125 }
126}
127impl<T> Clone for PtrKey<T> {
128 fn clone(&self) -> Self {
129 Self(self.0)
130 }
131}
132impl<T> PartialEq for PtrKey<T> {
133 fn eq(&self, other: &Self) -> bool {
134 self.0 == other.0
135 }
136}
137impl<T> Eq for PtrKey<T> {}
138impl<T> Hash for PtrKey<T> {
139 fn hash<H: Hasher>(&self, state: &mut H) {
140 self.0.hash(state)
141 }
142}
143#[allow(clippy::undocumented_unsafe_blocks, reason = "Force documented unsafe blocks in Starnix")]
144unsafe impl<T> Sync for PtrKey<T> {}
145#[allow(clippy::undocumented_unsafe_blocks, reason = "Force documented unsafe blocks in Starnix")]
146unsafe impl<T> Send for PtrKey<T> {}
147
148impl<T: std::fmt::Debug> std::fmt::Debug for PtrKey<T> {
149 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
150 self.0.fmt(f)
151 }
152}
153
154unsafe impl<T: Send + Sync + 'static> RcuDroppable for WeakKey<T> {}
156unsafe impl<T: 'static> RcuDroppable for PtrKey<T> {}