Skip to main content

nidus_core/module/
mod.rs

1//! Module graph primitives.
2
3mod graph;
4
5use std::{any::Any, future::Future, pin::Pin};
6
7use crate::{Container, Result};
8
9pub use graph::ModuleGraph;
10
11/// A Rust type that describes a Nidus module.
12pub trait Module {
13    /// Returns this module's static definition.
14    fn definition() -> ModuleDefinition;
15}
16
17/// Registers a provider type with a dependency container.
18pub trait ProviderRegistrant {
19    /// Registers this provider type.
20    fn register_provider(container: &mut Container) -> Result<()>;
21}
22
23/// Type-erased controller descriptor used by feature crates to assemble HTTP routers.
24pub trait ControllerRegistrant {
25    /// Returns the controller type name.
26    fn controller_name() -> &'static str;
27
28    /// Returns the controller route prefix.
29    fn controller_prefix() -> &'static str;
30
31    /// Builds the controller router as a type-erased value.
32    fn build_router(container: &Container) -> Result<Box<dyn Any + Send + Sync>>;
33
34    /// Returns generated controller route metadata as a type-erased value.
35    fn route_metadata() -> Box<dyn Any + Send + Sync>;
36}
37
38/// Registers a provider against a container.
39pub type ProviderRegistrar = fn(&mut Container) -> Result<()>;
40
41/// Creates an imported module definition.
42pub type ModuleDefinitionFactory = fn() -> ModuleDefinition;
43
44/// Initializes an async provider during application bootstrap.
45pub type AsyncProviderInitializer =
46    for<'a> fn(&'a mut Container) -> Pin<Box<dyn Future<Output = Result<()>> + Send + 'a>>;
47
48/// Type-erased controller runtime hooks.
49#[derive(Clone, Copy)]
50pub struct ControllerDescriptor {
51    name: &'static str,
52    prefix: fn() -> &'static str,
53    build_router: fn(&Container) -> Result<Box<dyn Any + Send + Sync>>,
54    route_metadata: fn() -> Box<dyn Any + Send + Sync>,
55}
56
57impl ControllerDescriptor {
58    /// Creates a descriptor for a typed controller.
59    pub fn new<C>() -> Self
60    where
61        C: ControllerRegistrant,
62    {
63        Self {
64            name: C::controller_name(),
65            prefix: C::controller_prefix,
66            build_router: C::build_router,
67            route_metadata: C::route_metadata,
68        }
69    }
70
71    /// Returns the controller type name.
72    pub fn name(&self) -> &'static str {
73        self.name
74    }
75
76    /// Returns the controller route prefix.
77    pub fn prefix(&self) -> &'static str {
78        (self.prefix)()
79    }
80
81    /// Builds the type-erased controller router.
82    pub fn build_router(&self, container: &Container) -> Result<Box<dyn Any + Send + Sync>> {
83        (self.build_router)(container)
84    }
85
86    /// Returns type-erased generated route metadata.
87    pub fn route_metadata(&self) -> Box<dyn Any + Send + Sync> {
88        (self.route_metadata)()
89    }
90}
91
92/// Explicit module metadata used to validate application structure.
93#[derive(Clone)]
94pub struct ModuleDefinition {
95    name: String,
96    imports: Vec<String>,
97    providers: Vec<String>,
98    controllers: Vec<String>,
99    exports: Vec<String>,
100    import_factories: Vec<ModuleDefinitionFactory>,
101    provider_registrars: Vec<ProviderRegistrar>,
102    controller_descriptors: Vec<ControllerDescriptor>,
103    async_initializers: Vec<AsyncProviderInitializer>,
104}
105
106impl ModuleDefinition {
107    /// Returns the module name.
108    pub fn name(&self) -> &str {
109        &self.name
110    }
111
112    /// Returns explicit imported modules.
113    pub fn imports(&self) -> &[String] {
114        &self.imports
115    }
116
117    /// Returns providers owned by the module.
118    pub fn providers(&self) -> &[String] {
119        &self.providers
120    }
121
122    /// Returns controllers owned by the module.
123    pub fn controllers(&self) -> &[String] {
124        &self.controllers
125    }
126
127    /// Returns providers exported to importing modules.
128    pub fn exports(&self) -> &[String] {
129        &self.exports
130    }
131
132    /// Returns typed import factories declared by this module.
133    pub fn import_factories(&self) -> &[ModuleDefinitionFactory] {
134        &self.import_factories
135    }
136
137    /// Returns provider registration callbacks declared by this module.
138    pub fn provider_registrars(&self) -> &[ProviderRegistrar] {
139        &self.provider_registrars
140    }
141
142    /// Returns controller runtime descriptors declared by this module.
143    pub fn controller_descriptors(&self) -> &[ControllerDescriptor] {
144        &self.controller_descriptors
145    }
146
147    /// Returns async provider initializers declared by this module.
148    pub fn async_initializers(&self) -> &[AsyncProviderInitializer] {
149        &self.async_initializers
150    }
151}
152
153impl std::fmt::Debug for ModuleDefinition {
154    fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
155        formatter
156            .debug_struct("ModuleDefinition")
157            .field("name", &self.name)
158            .field("imports", &self.imports)
159            .field("providers", &self.providers)
160            .field("controllers", &self.controllers)
161            .field("exports", &self.exports)
162            .finish_non_exhaustive()
163    }
164}
165
166impl PartialEq for ModuleDefinition {
167    fn eq(&self, other: &Self) -> bool {
168        self.name == other.name
169            && self.imports == other.imports
170            && self.providers == other.providers
171            && self.controllers == other.controllers
172            && self.exports == other.exports
173    }
174}
175
176impl Eq for ModuleDefinition {}
177
178/// Builder for explicit module definitions.
179#[derive(Debug)]
180pub struct ModuleBuilder {
181    definition: ModuleDefinition,
182}
183
184impl ModuleBuilder {
185    /// Starts a module definition.
186    pub fn new(name: impl Into<String>) -> Self {
187        Self {
188            definition: ModuleDefinition {
189                name: name.into(),
190                imports: Vec::new(),
191                providers: Vec::new(),
192                controllers: Vec::new(),
193                exports: Vec::new(),
194                import_factories: Vec::new(),
195                provider_registrars: Vec::new(),
196                controller_descriptors: Vec::new(),
197                async_initializers: Vec::new(),
198            },
199        }
200    }
201
202    /// Adds an explicit module import.
203    pub fn import(mut self, name: impl Into<String>) -> Self {
204        self.definition.imports.push(name.into());
205        self
206    }
207
208    /// Adds a typed module import.
209    pub fn import_typed<M>(mut self) -> Self
210    where
211        M: Module,
212    {
213        let definition = M::definition();
214        self.definition.imports.push(definition.name().to_owned());
215        self.definition.import_factories.push(M::definition);
216        self
217    }
218
219    /// Adds a provider declaration.
220    pub fn provider(mut self, name: impl Into<String>) -> Self {
221        self.definition.providers.push(name.into());
222        self
223    }
224
225    /// Adds a typed provider declaration and registration callback.
226    pub fn provider_typed<P>(mut self) -> Self
227    where
228        P: ProviderRegistrant,
229    {
230        self.definition.providers.push(
231            std::any::type_name::<P>()
232                .rsplit("::")
233                .next()
234                .unwrap()
235                .to_owned(),
236        );
237        self.definition
238            .provider_registrars
239            .push(P::register_provider);
240        self
241    }
242
243    /// Adds a controller declaration.
244    pub fn controller(mut self, name: impl Into<String>) -> Self {
245        self.definition.controllers.push(name.into());
246        self
247    }
248
249    /// Adds a typed controller declaration and runtime descriptor.
250    pub fn controller_typed<C>(mut self) -> Self
251    where
252        C: ControllerRegistrant,
253    {
254        self.definition
255            .controllers
256            .push(C::controller_name().to_owned());
257        self.definition
258            .controller_descriptors
259            .push(ControllerDescriptor::new::<C>());
260        self
261    }
262
263    /// Adds a provider export declaration.
264    pub fn export(mut self, name: impl Into<String>) -> Self {
265        self.definition.exports.push(name.into());
266        self
267    }
268
269    /// Adds a typed provider export declaration.
270    pub fn export_typed<P>(mut self) -> Self {
271        self.definition.exports.push(
272            std::any::type_name::<P>()
273                .rsplit("::")
274                .next()
275                .unwrap()
276                .to_owned(),
277        );
278        self
279    }
280
281    /// Adds an async provider initializer.
282    pub fn async_initializer(mut self, initializer: AsyncProviderInitializer) -> Self {
283        self.definition.async_initializers.push(initializer);
284        self
285    }
286
287    /// Completes the module definition.
288    pub fn build(self) -> ModuleDefinition {
289        self.definition
290    }
291}