type_registry/logical/
registration.rs

1use std::marker::PhantomData;
2use crate::logical::registered::Registered;
3use crate::logical::registry::Registry;
4use crate::raw::RegistryEntry;
5
6/// Existence of this type indicates that registration has occurred.
7pub struct Registration<
8    R: Registry + ?Sized,
9    T: Registered<R> + ?Sized
10> {
11    #[allow(dead_code)]
12    raw_entry: &'static RegistryEntry,
13    registry: PhantomData<fn(R)>,
14    marker: PhantomData<fn(T) -> T>
15}
16
17impl<
18    R: Registry + ?Sized,
19    T: Registered<R> + ?Sized
20> Registration<R, T> {
21    /// Creates a new registration.
22    /// 
23    /// SAFETY: [raw_entry] must have been created with the same types for [R]/[T].
24    #[doc(hidden)]
25    pub const unsafe fn new(raw_entry: &'static RegistryEntry) -> Self {
26        Registration {
27            raw_entry,
28            registry: PhantomData,
29            marker: PhantomData,
30        }
31    }
32}
33
34/// Should be used to implement [Registered::register].
35/// 
36/// For example:
37/// ```
38/// use type_registry::{registration, Registered, Registration, Registry};
39/// 
40/// struct MyRegistry;
41///
42/// impl Registry for MyRegistry {
43///     type TypeInfo = ();
44/// 
45///     fn name() -> &'static str {
46///         "My Registry"
47///     }
48/// }
49///
50/// struct MyType;
51///
52/// unsafe impl Registered<MyRegistry> for MyType {
53///     fn register() -> Registration<MyRegistry, Self> {
54///         registration!(MyRegistry, MyType)
55///     }
56///
57///     fn type_info() -> &'static <MyRegistry as Registry>::TypeInfo {
58///         todo!()
59///     }
60/// }
61///
62///
63/// ```
64#[macro_export]
65macro_rules! registration {
66    ($registry_type:ty, $registered_type:ty) => {
67        {
68            use $crate::reexports::linkme::distributed_slice;
69            use $crate::raw::{RegistryEntry, REGISTRY};
70            use $crate::{Registration};
71
72            #[distributed_slice(REGISTRY)]
73            #[linkme(crate=$crate::reexports::linkme)]
74            static REGISTRATION: RegistryEntry = RegistryEntry::new::<$registry_type, $registered_type>();
75
76            // SAFETY: Created with same types immediately above.
77            unsafe { Registration::<$registry_type, $registered_type>::new(&REGISTRATION) }
78        }
79    };
80}