1use std::any::{TypeId, type_name};
2use std::collections::HashMap;
3use std::hash::{BuildHasherDefault, Hash, Hasher};
4
5#[derive(Clone, Copy, Debug)]
7pub(crate) struct Key {
8 pub(crate) id: TypeId,
9 pub(crate) name: &'static str,
10}
11
12impl Key {
13 pub(crate) fn of<T: ?Sized + 'static>() -> Self {
14 Self {
15 id: TypeId::of::<T>(),
16 name: type_name::<T>(),
17 }
18 }
19}
20
21impl PartialEq for Key {
22 fn eq(&self, other: &Self) -> bool {
23 self.id == other.id
24 }
25}
26
27impl Eq for Key {}
28
29impl Hash for Key {
30 fn hash<H: Hasher>(&self, state: &mut H) {
31 self.id.hash(state);
32 }
33}
34
35pub(crate) struct TypeIdHasher(u64);
37
38impl Default for TypeIdHasher {
39 fn default() -> Self {
40 Self(0xcbf2_9ce4_8422_2325)
41 }
42}
43
44impl Hasher for TypeIdHasher {
45 fn finish(&self) -> u64 {
46 self.0
47 }
48
49 fn write(&mut self, bytes: &[u8]) {
50 for &byte in bytes {
51 self.0 ^= u64::from(byte);
52 self.0 = self.0.wrapping_mul(0x0100_0000_01b3);
53 }
54 }
55
56 fn write_u64(&mut self, n: u64) {
57 self.0 = n;
58 }
59}
60
61pub(crate) type KeyMap<V> = HashMap<Key, V, BuildHasherDefault<TypeIdHasher>>;
62
63#[derive(Clone, Copy, Debug, PartialEq, Eq)]
65pub struct Dependency {
66 key: Key,
67 all: bool,
68}
69
70impl Dependency {
71 pub fn on<T: ?Sized + 'static>() -> Self {
73 Self {
74 key: Key::of::<T>(),
75 all: false,
76 }
77 }
78
79 pub fn all<T: ?Sized + 'static>() -> Self {
81 Self {
82 key: Key::of::<T>(),
83 all: true,
84 }
85 }
86
87 pub fn type_name(&self) -> &'static str {
89 self.key.name
90 }
91
92 pub(crate) fn key(&self) -> Key {
93 self.key
94 }
95
96 pub(crate) fn is_all(&self) -> bool {
97 self.all
98 }
99}