a3s_boot/module/
dynamic.rs1use super::Module;
2use crate::{
3 BoxFuture, ControllerDefinition, MessagePatternDefinition, Middleware, MiddlewareConsumer,
4 ModuleRef, ProviderDefinition, ProviderToken, Result, RouteDefinition,
5 WebSocketGatewayDefinition,
6};
7use std::sync::Arc;
8
9#[derive(Clone)]
11pub struct DynamicModule {
12 name: &'static str,
13 imports: Vec<Arc<dyn Module>>,
14 forward_imports: Vec<Arc<dyn Module>>,
15 providers: Vec<ProviderDefinition>,
16 exports: Vec<ProviderToken>,
17 middleware: Vec<Arc<dyn Middleware>>,
18 controllers: Vec<ControllerDefinition>,
19 routes: Vec<RouteDefinition>,
20 gateways: Vec<WebSocketGatewayDefinition>,
21 message_patterns: Vec<MessagePatternDefinition>,
22 global: bool,
23 route_prefix: Option<String>,
24 middleware_consumer: MiddlewareConsumer,
25}
26
27impl DynamicModule {
28 pub fn new(name: &'static str) -> Self {
29 Self {
30 name,
31 imports: Vec::new(),
32 forward_imports: Vec::new(),
33 providers: Vec::new(),
34 exports: Vec::new(),
35 middleware: Vec::new(),
36 controllers: Vec::new(),
37 routes: Vec::new(),
38 gateways: Vec::new(),
39 message_patterns: Vec::new(),
40 global: false,
41 route_prefix: None,
42 middleware_consumer: MiddlewareConsumer::new(),
43 }
44 }
45
46 pub fn import<M>(mut self, module: M) -> Self
47 where
48 M: Module,
49 {
50 self.imports.push(Arc::new(module));
51 self
52 }
53
54 pub fn import_arc(mut self, module: Arc<dyn Module>) -> Self {
55 self.imports.push(module);
56 self
57 }
58
59 pub fn forward_import<M>(mut self, module: M) -> Self
60 where
61 M: Module,
62 {
63 self.forward_imports.push(Arc::new(module));
64 self
65 }
66
67 pub fn forward_import_arc(mut self, module: Arc<dyn Module>) -> Self {
68 self.forward_imports.push(module);
69 self
70 }
71
72 pub fn provider(mut self, provider: ProviderDefinition) -> Self {
73 self.providers.push(provider);
74 self
75 }
76
77 pub fn export<T>(self) -> Self
78 where
79 T: Send + Sync + 'static,
80 {
81 self.export_token(ProviderToken::of::<T>())
82 }
83
84 pub fn export_named(self, token: impl Into<String>) -> Self {
85 self.export_token(ProviderToken::named(token))
86 }
87
88 pub fn export_token(mut self, token: ProviderToken) -> Self {
89 if !self.exports.contains(&token) {
90 self.exports.push(token);
91 }
92 self
93 }
94
95 pub fn middleware<M>(mut self, middleware: M) -> Self
96 where
97 M: Middleware,
98 {
99 self.middleware.push(Arc::new(middleware));
100 self
101 }
102
103 pub fn middleware_arc(mut self, middleware: Arc<dyn Middleware>) -> Self {
104 self.middleware.push(middleware);
105 self
106 }
107
108 pub fn configure_middleware<F>(mut self, configure: F) -> Result<Self>
109 where
110 F: FnOnce(&mut MiddlewareConsumer) -> Result<()>,
111 {
112 configure(&mut self.middleware_consumer)?;
113 Ok(self)
114 }
115
116 pub fn controller(mut self, controller: ControllerDefinition) -> Self {
117 self.controllers.push(controller);
118 self
119 }
120
121 pub fn route(mut self, route: RouteDefinition) -> Self {
122 self.routes.push(route);
123 self
124 }
125
126 pub fn route_prefix(mut self, prefix: impl Into<String>) -> Self {
127 self.route_prefix = Some(prefix.into());
128 self
129 }
130
131 pub fn gateway(mut self, gateway: WebSocketGatewayDefinition) -> Self {
132 self.gateways.push(gateway);
133 self
134 }
135
136 pub fn message_pattern(mut self, pattern: MessagePatternDefinition) -> Self {
137 self.message_patterns.push(pattern);
138 self
139 }
140
141 pub fn global(mut self) -> Self {
142 self.global = true;
143 self
144 }
145}
146
147impl Module for DynamicModule {
148 fn name(&self) -> &'static str {
149 self.name
150 }
151
152 fn imports(&self) -> Vec<Arc<dyn Module>> {
153 self.imports.clone()
154 }
155
156 fn forward_imports(&self) -> Vec<Arc<dyn Module>> {
157 self.forward_imports.clone()
158 }
159
160 fn providers(&self) -> Result<Vec<ProviderDefinition>> {
161 Ok(self.providers.clone())
162 }
163
164 fn exports(&self) -> Result<Vec<ProviderToken>> {
165 Ok(self.exports.clone())
166 }
167
168 fn is_global(&self) -> bool {
169 self.global
170 }
171
172 fn route_prefix(&self) -> Option<&str> {
173 self.route_prefix.as_deref()
174 }
175
176 fn middleware(&self) -> Vec<Arc<dyn Middleware>> {
177 self.middleware.clone()
178 }
179
180 fn configure(&self, consumer: &mut MiddlewareConsumer, _module_ref: &ModuleRef) -> Result<()> {
181 consumer.extend(self.middleware_consumer.clone());
182 Ok(())
183 }
184
185 fn controllers(&self, _module_ref: &ModuleRef) -> Result<Vec<ControllerDefinition>> {
186 Ok(self.controllers.clone())
187 }
188
189 fn routes(&self) -> Result<Vec<RouteDefinition>> {
190 Ok(self.routes.clone())
191 }
192
193 fn gateways(&self, _module_ref: &ModuleRef) -> Result<Vec<WebSocketGatewayDefinition>> {
194 Ok(self.gateways.clone())
195 }
196
197 fn message_patterns(&self, _module_ref: &ModuleRef) -> Result<Vec<MessagePatternDefinition>> {
198 Ok(self.message_patterns.clone())
199 }
200
201 fn on_application_bootstrap(&self, _module_ref: ModuleRef) -> BoxFuture<'static, Result<()>> {
202 Box::pin(async { Ok(()) })
203 }
204
205 fn on_application_shutdown(&self, _module_ref: ModuleRef) -> BoxFuture<'static, Result<()>> {
206 Box::pin(async { Ok(()) })
207 }
208}