1use crate::core::{bootstrap, CoreError, Module, RuestApplication};
4use crate::http::axum::Router;
5use crate::security::{apply_jwt_layer, JwtService, SecurityConfig};
6
7pub struct AppBuilder {
9 pub app: RuestApplication,
10 pub router: Router,
11}
12
13pub fn bootstrap_app<M>(root: M) -> Result<AppBuilder, CoreError>
17where
18 M: Module + ModuleWireRoutes,
19{
20 let app = bootstrap(root)?;
21 let router = M::wire_routes(Router::new(), &app.container)
22 .map_err(|e| CoreError::ModuleConfig(e.to_string()))?;
23 Ok(AppBuilder { app, router })
24}
25
26pub trait ModuleWireRoutes {
28 fn wire_routes(
29 router: Router,
30 container: &crate::di::Container,
31 ) -> Result<Router, crate::di::DiError>;
32}
33
34impl AppBuilder {
35 pub fn port(mut self, port: u16) -> Self {
36 self.app.set_port(port);
37 self
38 }
39
40 pub fn host(mut self, host: impl Into<String>) -> Self {
41 self.app.set_host(host);
42 self
43 }
44
45 pub async fn listen(self) -> Result<(), CoreError> {
46 crate::http::serve(self.app, self.router)
47 .await
48 .map_err(|e| CoreError::Bootstrap(e.to_string()))
49 }
50
51 pub fn build(self) -> (RuestApplication, Router) {
52 (self.app, self.router)
53 }
54
55 pub fn with_jwt_auth(mut self, config: SecurityConfig) -> Result<Self, CoreError> {
60 if self.app.container.get::<JwtService>().is_err() {
61 crate::security::register_jwt_provider(&self.app.container, config.clone())
62 .map_err(|e| CoreError::ModuleConfig(e.to_string()))?;
63 }
64
65 let jwt = self
66 .app
67 .container
68 .get::<JwtService>()
69 .map_err(|e| CoreError::ModuleConfig(e.to_string()))?;
70
71 self.router = apply_jwt_layer(self.router, jwt, &config);
72 Ok(self)
73 }
74}