1use std::{hash::Hash, marker::PhantomData, sync::Arc};
3
4#[derive(Clone, Debug, Hash, PartialEq, Eq)]
6pub enum HandleKey {
7 Str(&'static str),
8 String(String),
9 Number(usize),
10}
11
12impl From<String> for HandleKey {
13 fn from(s: String) -> Self {
14 HandleKey::String(s)
15 }
16}
17
18impl From<&String> for HandleKey {
19 fn from(s: &String) -> Self {
20 HandleKey::String(s.clone())
21 }
22}
23
24impl From<usize> for HandleKey {
25 fn from(k: usize) -> Self {
26 HandleKey::Number(k)
27 }
28}
29
30impl From<&str> for HandleKey {
31 fn from(s: &str) -> Self {
32 HandleKey::from(s.to_string())
33 }
34}
35
36pub struct Handle<T> {
38 pub key: HandleKey,
40 pub count: Option<Arc<()>>,
42 _phantom: PhantomData<T>,
43}
44
45impl<T> std::fmt::Debug for Handle<T> {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 f.debug_struct(&format!("Handle<{}>", std::any::type_name::<T>()))
48 .field("key", &self.key)
49 .field(
50 "references",
51 &format!("{:?}", self.count.as_ref().map(|c| Arc::strong_count(c))),
52 )
53 .finish()
54 }
55}
56
57impl<T> Clone for Handle<T> {
58 fn clone(&self) -> Self {
59 Handle {
60 key: self.key.clone(),
61 count: self.count.clone(),
62 _phantom: PhantomData,
63 }
64 }
65}
66
67impl<T> Hash for Handle<T> {
68 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
69 self.key.hash(state);
70 }
71}
72
73impl<T> PartialEq for Handle<T> {
74 fn eq(&self, other: &Self) -> bool {
75 self.key == other.key
76 }
77}
78
79impl<T> Eq for Handle<T> {
80 fn assert_receiver_is_total_eq(&self) {}
81}
82
83impl<T> Handle<T> {
84 pub fn new<K>(k: K) -> Self
85 where
86 HandleKey: From<K>,
87 {
88 Handle {
89 key: HandleKey::from(k),
90 count: Some(Arc::new(())),
91 _phantom: PhantomData,
92 }
93 }
94
95 pub const fn from_static(key: &'static str) -> Handle<T> {
96 Handle {
97 key: HandleKey::Str(key),
98 count: None,
99 _phantom: PhantomData,
100 }
101 }
102}