1use std::{
10 any::{Any, TypeId},
11 fmt,
12 hash::{Hash, Hasher},
13 sync::atomic::{AtomicU64, Ordering},
14};
15
16static NEXT_UNIQUE_KEY: AtomicU64 = AtomicU64::new(1);
17
18fn next_unique_key() -> u64 {
19 NEXT_UNIQUE_KEY
20 .fetch_update(Ordering::Relaxed, Ordering::Relaxed, |id| id.checked_add(1))
21 .expect("unique key identity space exhausted")
22}
23
24#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
26pub struct KeyId {
27 type_id: TypeId,
28 hash: u64,
29}
30
31impl KeyId {
32 #[must_use]
33 pub const fn type_id(self) -> TypeId {
34 self.type_id
35 }
36
37 #[must_use]
38 pub const fn hash(self) -> u64 {
39 self.hash
40 }
41}
42
43pub trait Key: Any + fmt::Debug {
46 fn key_id(&self) -> KeyId;
48
49 fn eq_key(&self, other: &dyn Key) -> bool;
52
53 fn clone_box(&self) -> Box<dyn Key>;
55
56 fn as_any(&self) -> &dyn Any;
58}
59
60pub trait LocalKey: Key {}
62
63#[derive(Clone, Copy, PartialEq, Eq, Hash)]
66pub struct UniqueKey(u64);
67
68impl UniqueKey {
69 #[must_use]
70 pub fn new() -> Self {
71 Self(next_unique_key())
72 }
73
74 #[must_use]
75 pub const fn id(self) -> u64 {
76 self.0
77 }
78}
79
80impl Default for UniqueKey {
81 fn default() -> Self {
82 Self::new()
83 }
84}
85
86impl fmt::Debug for UniqueKey {
87 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 f.debug_tuple("UniqueKey").field(&self.0).finish()
89 }
90}
91
92impl Key for UniqueKey {
93 fn key_id(&self) -> KeyId {
94 KeyId {
95 type_id: TypeId::of::<Self>(),
96 hash: self.0,
97 }
98 }
99
100 fn eq_key(&self, other: &dyn Key) -> bool {
101 other
102 .as_any()
103 .downcast_ref::<Self>()
104 .is_some_and(|other| self == other)
105 }
106
107 fn clone_box(&self) -> Box<dyn Key> {
108 Box::new(*self)
109 }
110
111 fn as_any(&self) -> &dyn Any {
112 self
113 }
114}
115
116impl LocalKey for UniqueKey {}
117
118#[derive(Clone, Debug, PartialEq, Eq, Hash)]
121pub struct ValueKey<T>(pub T);
122
123impl<T> ValueKey<T> {
124 #[must_use]
125 pub const fn new(value: T) -> Self {
126 Self(value)
127 }
128
129 #[must_use]
130 pub const fn value(&self) -> &T {
131 &self.0
132 }
133}
134
135impl<T> Key for ValueKey<T>
136where
137 T: Any + Clone + Eq + Hash + fmt::Debug,
138{
139 fn key_id(&self) -> KeyId {
140 let mut hasher = std::collections::hash_map::DefaultHasher::new();
141 self.hash(&mut hasher);
142 KeyId {
143 type_id: TypeId::of::<Self>(),
144 hash: hasher.finish(),
145 }
146 }
147
148 fn eq_key(&self, other: &dyn Key) -> bool {
149 other
150 .as_any()
151 .downcast_ref::<Self>()
152 .is_some_and(|other| self == other)
153 }
154
155 fn clone_box(&self) -> Box<dyn Key> {
156 Box::new(self.clone())
157 }
158
159 fn as_any(&self) -> &dyn Any {
160 self
161 }
162}
163
164impl<T> LocalKey for ValueKey<T> where T: Any + Clone + Eq + Hash + fmt::Debug {}
165
166pub type StringKey = ValueKey<String>;
168
169pub type KeyObject<T> = ValueKey<T>;
171
172pub struct KeyHandle(Box<dyn Key>);
175
176impl KeyHandle {
177 #[must_use]
178 pub fn new<K>(key: K) -> Self
179 where
180 K: Key,
181 {
182 Self(Box::new(key))
183 }
184
185 #[must_use]
186 pub fn as_key(&self) -> &dyn Key {
187 &*self.0
188 }
189
190 #[must_use]
191 pub fn key_id(&self) -> KeyId {
192 self.0.key_id()
193 }
194}
195
196impl Clone for KeyHandle {
197 fn clone(&self) -> Self {
198 Self(self.0.clone_box())
199 }
200}
201
202impl fmt::Debug for KeyHandle {
203 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
204 f.debug_tuple("KeyHandle").field(&self.0).finish()
205 }
206}
207
208impl PartialEq for KeyHandle {
209 fn eq(&self, other: &Self) -> bool {
210 self.0.eq_key(&*other.0)
211 }
212}
213
214impl Eq for KeyHandle {}
215
216impl Hash for KeyHandle {
217 fn hash<H: Hasher>(&self, state: &mut H) {
218 Hash::hash(&self.key_id(), state);
219 }
220}
221
222impl Key for KeyHandle {
223 fn key_id(&self) -> KeyId {
224 self.0.key_id()
225 }
226
227 fn eq_key(&self, other: &dyn Key) -> bool {
228 other
229 .as_any()
230 .downcast_ref::<Self>()
231 .is_some_and(|other| self == other)
232 }
233
234 fn clone_box(&self) -> Box<dyn Key> {
235 Box::new(self.clone())
236 }
237
238 fn as_any(&self) -> &dyn Any {
239 self
240 }
241}
242
243impl LocalKey for KeyHandle {}
244
245impl From<String> for KeyHandle {
246 fn from(value: String) -> Self {
247 Self::new(StringKey::new(value))
248 }
249}
250
251impl From<&str> for KeyHandle {
252 fn from(value: &str) -> Self {
253 Self::new(StringKey::new(value.to_owned()))
254 }
255}
256
257impl From<UniqueKey> for KeyHandle {
258 fn from(value: UniqueKey) -> Self {
259 Self::new(value)
260 }
261}
262
263impl<T> From<ValueKey<T>> for KeyHandle
264where
265 T: Any + Clone + Eq + Hash + fmt::Debug,
266{
267 fn from(value: ValueKey<T>) -> Self {
268 Self::new(value)
269 }
270}