Skip to main content

a3s_boot/module/
dynamic.rs

1use super::Module;
2use crate::{
3    BoxFuture, ControllerDefinition, MessagePatternDefinition, Middleware, ModuleRef,
4    ProviderDefinition, ProviderToken, Result, RouteDefinition, WebSocketGatewayDefinition,
5};
6use std::sync::Arc;
7
8/// Runtime-built module for configuration-driven imports and providers.
9#[derive(Clone)]
10pub struct DynamicModule {
11    name: &'static str,
12    imports: Vec<Arc<dyn Module>>,
13    providers: Vec<ProviderDefinition>,
14    exports: Vec<ProviderToken>,
15    middleware: Vec<Arc<dyn Middleware>>,
16    controllers: Vec<ControllerDefinition>,
17    routes: Vec<RouteDefinition>,
18    gateways: Vec<WebSocketGatewayDefinition>,
19    message_patterns: Vec<MessagePatternDefinition>,
20    global: bool,
21}
22
23impl DynamicModule {
24    pub fn new(name: &'static str) -> Self {
25        Self {
26            name,
27            imports: Vec::new(),
28            providers: Vec::new(),
29            exports: Vec::new(),
30            middleware: Vec::new(),
31            controllers: Vec::new(),
32            routes: Vec::new(),
33            gateways: Vec::new(),
34            message_patterns: Vec::new(),
35            global: false,
36        }
37    }
38
39    pub fn import<M>(mut self, module: M) -> Self
40    where
41        M: Module,
42    {
43        self.imports.push(Arc::new(module));
44        self
45    }
46
47    pub fn import_arc(mut self, module: Arc<dyn Module>) -> Self {
48        self.imports.push(module);
49        self
50    }
51
52    pub fn provider(mut self, provider: ProviderDefinition) -> Self {
53        self.providers.push(provider);
54        self
55    }
56
57    pub fn export<T>(self) -> Self
58    where
59        T: Send + Sync + 'static,
60    {
61        self.export_token(ProviderToken::of::<T>())
62    }
63
64    pub fn export_named(self, token: impl Into<String>) -> Self {
65        self.export_token(ProviderToken::named(token))
66    }
67
68    pub fn export_token(mut self, token: ProviderToken) -> Self {
69        if !self.exports.contains(&token) {
70            self.exports.push(token);
71        }
72        self
73    }
74
75    pub fn middleware<M>(mut self, middleware: M) -> Self
76    where
77        M: Middleware,
78    {
79        self.middleware.push(Arc::new(middleware));
80        self
81    }
82
83    pub fn middleware_arc(mut self, middleware: Arc<dyn Middleware>) -> Self {
84        self.middleware.push(middleware);
85        self
86    }
87
88    pub fn controller(mut self, controller: ControllerDefinition) -> Self {
89        self.controllers.push(controller);
90        self
91    }
92
93    pub fn route(mut self, route: RouteDefinition) -> Self {
94        self.routes.push(route);
95        self
96    }
97
98    pub fn gateway(mut self, gateway: WebSocketGatewayDefinition) -> Self {
99        self.gateways.push(gateway);
100        self
101    }
102
103    pub fn message_pattern(mut self, pattern: MessagePatternDefinition) -> Self {
104        self.message_patterns.push(pattern);
105        self
106    }
107
108    pub fn global(mut self) -> Self {
109        self.global = true;
110        self
111    }
112}
113
114impl Module for DynamicModule {
115    fn name(&self) -> &'static str {
116        self.name
117    }
118
119    fn imports(&self) -> Vec<Arc<dyn Module>> {
120        self.imports.clone()
121    }
122
123    fn providers(&self) -> Result<Vec<ProviderDefinition>> {
124        Ok(self.providers.clone())
125    }
126
127    fn exports(&self) -> Result<Vec<ProviderToken>> {
128        Ok(self.exports.clone())
129    }
130
131    fn is_global(&self) -> bool {
132        self.global
133    }
134
135    fn middleware(&self) -> Vec<Arc<dyn Middleware>> {
136        self.middleware.clone()
137    }
138
139    fn controllers(&self, _module_ref: &ModuleRef) -> Result<Vec<ControllerDefinition>> {
140        Ok(self.controllers.clone())
141    }
142
143    fn routes(&self) -> Result<Vec<RouteDefinition>> {
144        Ok(self.routes.clone())
145    }
146
147    fn gateways(&self, _module_ref: &ModuleRef) -> Result<Vec<WebSocketGatewayDefinition>> {
148        Ok(self.gateways.clone())
149    }
150
151    fn message_patterns(&self, _module_ref: &ModuleRef) -> Result<Vec<MessagePatternDefinition>> {
152        Ok(self.message_patterns.clone())
153    }
154
155    fn on_application_bootstrap(&self, _module_ref: ModuleRef) -> BoxFuture<'static, Result<()>> {
156        Box::pin(async { Ok(()) })
157    }
158
159    fn on_application_shutdown(&self, _module_ref: ModuleRef) -> BoxFuture<'static, Result<()>> {
160        Box::pin(async { Ok(()) })
161    }
162}