Skip to main content

rust_ef/
registration.rs

1//! Compile-time entity registration via `inventory`.
2//!
3//! The `#[derive(EntityType)]` macro emits an `inventory::submit!` for each
4//! entity type, registering a type-erased [`EntityRegistration`]. The
5//! `DbContext` discovers these at runtime via
6//! `inventory::iter::<EntityRegistration>()` (see `DbContext::discover_entities`).
7//!
8//! Similarly, `#[entity(T)]` applied to `impl IEntityTypeConfiguration<T>`
9//! blocks emits an [`EntityConfigRegistration`], whose `apply_fn` is invoked by
10//! `DbContext::discover_entities()` to apply Fluent API overrides to the
11//! `ModelBuilder`.
12
13use crate::metadata::EntityTypeMeta;
14use crate::model_builder::ModelBuilder;
15use std::any::TypeId;
16
17/// Type-erased registration for an entity type.
18///
19/// Emitted automatically by `#[derive(EntityType)]`. Collected at link time
20/// via `inventory::collect!`, so every entity type compiled into the final
21/// binary is visible to `DbContext::discover_entities()`.
22#[derive(Debug)]
23pub struct EntityRegistration {
24    pub type_id: TypeId,
25    pub type_name: &'static str,
26    pub meta_fn: fn() -> EntityTypeMeta,
27    /// Which DbContext key this entity belongs to.
28    /// `None` = default context; `Some("key")` = keyed context.
29    /// Set by `#[context("key")]` on the entity struct.
30    pub context_key: Option<&'static str>,
31}
32
33impl EntityRegistration {
34    pub fn meta(&self) -> EntityTypeMeta {
35        (self.meta_fn)()
36    }
37}
38
39inventory::collect!(EntityRegistration);
40
41/// Type-erased registration for an `IEntityTypeConfiguration<T>` impl block.
42///
43/// Emitted by the `#[entity(T)]` attribute macro. The `apply_fn`
44/// instantiates the configuration via `Default::default()` and invokes
45/// `IEntityTypeConfiguration::configure(&mut EntityTypeBuilder)` on a
46/// freshly-borrowed `ModelBuilder`.
47#[derive(Clone, Copy)]
48pub struct EntityConfigRegistration {
49    pub type_id: TypeId,
50    pub type_name: &'static str,
51    pub apply_fn: fn(&mut ModelBuilder),
52    /// Which DbContext key this configuration applies to.
53    /// `None` = default context; `Some("key")` = keyed context.
54    /// Set by `#[entity(T, "key")]` attribute's optional second argument.
55    pub context_key: Option<&'static str>,
56}
57
58impl std::fmt::Debug for EntityConfigRegistration {
59    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
60        f.debug_struct("EntityConfigRegistration")
61            .field("type_id", &self.type_id)
62            .field("type_name", &self.type_name)
63            .finish()
64    }
65}
66
67inventory::collect!(EntityConfigRegistration);