Skip to main content

a3s_boot/module/
mod.rs

1use crate::{
2    BoxFuture, ControllerDefinition, MessagePatternDefinition, Middleware, MiddlewareConsumer,
3    ModuleRef, ProviderDefinition, ProviderToken, Result, RouteDefinition,
4    WebSocketGatewayDefinition,
5};
6use std::sync::Arc;
7
8mod dynamic;
9
10pub use dynamic::DynamicModule;
11
12/// A module contributes imports, providers, controllers, and routes.
13///
14/// This is the Rust equivalent of a Nest module boundary. Modules organize the
15/// application graph; HTTP serving remains delegated to an adapter.
16pub trait Module: Send + Sync + 'static {
17    /// Stable module name used for deduplication and diagnostics.
18    fn name(&self) -> &'static str;
19
20    /// Imported modules that should be registered before this module.
21    fn imports(&self) -> Vec<Arc<dyn Module>> {
22        Vec::new()
23    }
24
25    /// Forward module imports for intentional circular module relationships.
26    ///
27    /// This mirrors the module side of Nest's `forwardRef(...)`. Forward imports
28    /// can reference a module that is currently being registered; exported
29    /// providers become visible once the target module finishes registration.
30    /// Provider cycles should still use lazy [`crate::ProviderRef`] handles.
31    fn forward_imports(&self) -> Vec<Arc<dyn Module>> {
32        Vec::new()
33    }
34
35    /// Providers exported into the application container.
36    fn providers(&self) -> Result<Vec<ProviderDefinition>> {
37        Ok(Vec::new())
38    }
39
40    /// Providers this module exposes to importing modules.
41    fn exports(&self) -> Result<Vec<ProviderToken>> {
42        Ok(Vec::new())
43    }
44
45    /// Whether exported providers should be visible to every module scope.
46    fn is_global(&self) -> bool {
47        false
48    }
49
50    /// Optional HTTP route prefix applied to controllers and direct routes in this module and its imports.
51    fn route_prefix(&self) -> Option<&str> {
52        None
53    }
54
55    /// Middleware applied to controllers and direct routes declared by this module.
56    fn middleware(&self) -> Vec<Arc<dyn Middleware>> {
57        Vec::new()
58    }
59
60    /// Configure route-scoped middleware with a Nest-style consumer.
61    fn configure(&self, _consumer: &mut MiddlewareConsumer, _module_ref: &ModuleRef) -> Result<()> {
62        Ok(())
63    }
64
65    /// Controller route groups built with access to the provider container.
66    fn controllers(&self, _module_ref: &ModuleRef) -> Result<Vec<ControllerDefinition>> {
67        Ok(Vec::new())
68    }
69
70    /// Framework-neutral routes contributed directly by this module.
71    fn routes(&self) -> Result<Vec<RouteDefinition>> {
72        Ok(Vec::new())
73    }
74
75    /// WebSocket gateways contributed by this module.
76    fn gateways(&self, _module_ref: &ModuleRef) -> Result<Vec<WebSocketGatewayDefinition>> {
77        Ok(Vec::new())
78    }
79
80    /// Microservice message patterns contributed by this module.
81    fn message_patterns(&self, _module_ref: &ModuleRef) -> Result<Vec<MessagePatternDefinition>> {
82        Ok(Vec::new())
83    }
84
85    /// Lifecycle hook called after imports and providers are registered.
86    fn on_module_init(&self, _module_ref: &ModuleRef) -> Result<()> {
87        Ok(())
88    }
89
90    /// Async lifecycle hook called by hosts that want startup work before serve.
91    fn on_application_bootstrap(&self, _module_ref: ModuleRef) -> BoxFuture<'static, Result<()>> {
92        Box::pin(async { Ok(()) })
93    }
94
95    /// Async lifecycle hook called when shutdown begins.
96    fn on_module_destroy(
97        &self,
98        _module_ref: ModuleRef,
99        _signal: Option<String>,
100    ) -> BoxFuture<'static, Result<()>> {
101        Box::pin(async { Ok(()) })
102    }
103
104    /// Async lifecycle hook called after module destroy hooks and before final shutdown hooks.
105    fn before_application_shutdown(
106        &self,
107        _module_ref: ModuleRef,
108        _signal: Option<String>,
109    ) -> BoxFuture<'static, Result<()>> {
110        Box::pin(async { Ok(()) })
111    }
112
113    /// Async lifecycle hook called by hosts that need graceful shutdown cleanup.
114    fn on_application_shutdown(&self, _module_ref: ModuleRef) -> BoxFuture<'static, Result<()>> {
115        Box::pin(async { Ok(()) })
116    }
117
118    /// Signal-aware variant of [`Module::on_application_shutdown`].
119    fn on_application_shutdown_with_signal(
120        &self,
121        module_ref: ModuleRef,
122        _signal: Option<String>,
123    ) -> BoxFuture<'static, Result<()>> {
124        self.on_application_shutdown(module_ref)
125    }
126}