type_registry/logical/
registration_id.rs1use std::any::TypeId;
2use std::borrow::Borrow;
3use std::fmt::{Debug, Display, Formatter};
4use std::hash::{Hash, Hasher};
5use std::marker::PhantomData;
6use crate::logical::{Registered, RegistryEntry, RegistryExt};
7use crate::logical::registry::Registry;
8use crate::raw::{RegistrationId as RawRegistrationId, RegistryEntry as RawRegistryEntry};
9
10pub struct RegistrationId<R: Registry + ?Sized> {
12 raw_id: RawRegistrationId,
14 registry_index: usize,
16 registry: PhantomData<fn(R)>
18}
19
20impl<R: Registry + ?Sized> RegistrationId<R> {
21 pub(crate) fn new(
22 raw_index: usize,
23 registry_index: usize
24 ) -> Self {
25 Self {
26 raw_id: RawRegistrationId::new(raw_index),
27 registry_index,
28 registry: PhantomData
29 }
30 }
31
32 #[allow(dead_code)]
33 pub(crate) fn raw(self) -> RawRegistrationId {
34 self.raw_id
35 }
36
37 pub fn index(self) -> usize {
39 self.registry_index
40 }
41
42 pub fn entry(self) -> RegistryEntry<R> {
44 unsafe { RegistryEntry::new_unchecked(self.raw_id.entry()) }
46 }
47
48 pub fn metadata(self) -> &'static R::TypeInfo {
49 self.entry().type_info()
50 }
51
52 pub fn of<T: Registered<R> + ?Sized>() -> Self {
53 unsafe {
55 Self::from_type_id_unchecked(TypeId::of::<T>())
56 }
57 }
58
59 pub(crate) unsafe fn from_raw_entry_unchecked(raw_entry: &RawRegistryEntry) -> Self {
61 Self::from_type_id_unchecked(raw_entry.type_id())
62 }
63
64 pub(crate) unsafe fn from_type_id_unchecked(type_id: TypeId) -> Self {
66 *R::index::<RawRegistryEntry>().get(&type_id).expect("type is registered")
67 }
68}
69
70impl<R: Registry + ?Sized> Clone for RegistrationId<R> {
73 fn clone(&self) -> Self {
74 Self::new(self.raw_id.index(), self.registry_index)
75 }
76}
77
78impl<R: Registry + ?Sized> Copy for RegistrationId<R> {}
79
80impl<R: Registry + ?Sized> Debug for RegistrationId<R> {
87 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
88 f.debug_struct(&format!("RegistrationId<{}>", std::any::type_name::<R>()))
90 .field("raw_id", &self.raw_id)
91 .field("registry_index", &self.registry_index)
92 .field("registry", &R::name())
93 .finish()
94 }
95}
96
97impl<R: Registry + ?Sized> PartialEq for RegistrationId<R> {
98 fn eq(&self, other: &Self) -> bool {
99 self.raw_id == other.raw_id
100 }
101}
102
103impl<R: Registry + ?Sized> Eq for RegistrationId<R> {}
104
105impl<R: Registry + ?Sized> Hash for RegistrationId<R> {
106 fn hash<H: Hasher>(&self, state: &mut H) {
107 self.raw_id.hash(state)
108 }
109}
110
111impl<R: Registry + ?Sized> Display for RegistrationId<R> {
112 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
113 let index = self.registry_index;
114 let name = R::name();
115 f.write_fmt(format_args!("'{name}' registration ID #{index}"))
116 }
117}
118
119impl<R: Registry + ?Sized> From<RegistrationId<R>> for RawRegistrationId {
120 fn from(value: RegistrationId<R>) -> Self {
121 value.raw_id
122 }
123}
124
125impl<R: Registry + ?Sized> PartialEq<RawRegistrationId> for RegistrationId<R> {
126 fn eq(&self, other: &RawRegistrationId) -> bool {
127 &self.raw_id == other
128 }
129}
130
131impl<R: Registry + ?Sized> PartialEq<RegistrationId<R>> for RawRegistrationId {
132 fn eq(&self, other: &RegistrationId<R>) -> bool {
133 self == &other.raw_id
134 }
135}
136
137impl<R: Registry + ?Sized> Borrow<RawRegistrationId> for RegistrationId<R> {
138 fn borrow(&self) -> &RawRegistrationId {
139 &self.raw_id
140 }
141}