handle_key/
lib.rs

1//! Keys that serve as a means of accessing an object in a map.
2use std::{hash::Hash, marker::PhantomData, sync::Arc};
3
4/// A handle key.
5#[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
36/// A typed asset handle.
37pub struct Handle<T> {
38    // Underlying key used for comparison
39    pub key: HandleKey,
40    // Used to count how many things own a clone of the handle.
41    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}