shared/extensions/
manager.rs1use crate::{
2 State,
3 extensions::{
4 ConstructedExtension, ExtensionPermissionsBuilder, ExtensionRouteBuilder,
5 commands::CliCommandGroupBuilder,
6 },
7};
8use std::sync::Arc;
9use tokio::sync::{RwLock, RwLockReadGuard};
10
11pub struct ExtensionManager {
12 vec: RwLock<Vec<ConstructedExtension>>,
13}
14
15impl ExtensionManager {
16 pub fn new(vec: Vec<ConstructedExtension>) -> Self {
17 Self {
18 vec: RwLock::new(vec),
19 }
20 }
21
22 pub async fn init(
23 &self,
24 state: State,
25 ) -> (
26 ExtensionRouteBuilder,
27 super::background_tasks::BackgroundTaskBuilder,
28 super::shutdown_handlers::ShutdownHandlerBuilder,
29 ) {
30 let mut route_builder = ExtensionRouteBuilder::new(state.clone());
31 let mut email_templates_builder =
32 super::email_templates::ExtensionEmailTemplateBuilder::default();
33 let mut background_tasks_builder =
34 super::background_tasks::BackgroundTaskBuilder::new(state.clone());
35 let mut shutdown_handlers_builder =
36 super::shutdown_handlers::ShutdownHandlerBuilder::new(state.clone());
37 let mut permissions_builder = ExtensionPermissionsBuilder::new(
38 crate::permissions::BASE_USER_PERMISSIONS.clone(),
39 crate::permissions::BASE_ADMIN_PERMISSIONS.clone(),
40 crate::permissions::BASE_SERVER_PERMISSIONS.clone(),
41 );
42
43 for ext in self.vec.read().await.iter() {
44 let deserializer = ext.settings_deserializer(state.clone()).await;
45 crate::settings::SETTINGS_DESER_EXTENSIONS
46 .write()
47 .insert(ext.package_name, deserializer);
48 }
49 state.settings.invalidate_cache().await;
50
51 for ext in self.vec.write().await.iter_mut() {
52 let ext = match Arc::get_mut(&mut ext.extension) {
53 Some(ext) => ext,
54 None => {
55 panic!(
56 "Failed to get mutable reference to extension {}. This should NEVER happen.",
57 ext.package_name
58 );
59 }
60 };
61
62 ext.initialize(state.clone()).await;
63
64 route_builder = ext.initialize_router(state.clone(), route_builder).await;
65 email_templates_builder = ext
66 .initialize_email_templates(state.clone(), email_templates_builder)
67 .await;
68 background_tasks_builder = ext
69 .initialize_background_tasks(state.clone(), background_tasks_builder)
70 .await;
71 shutdown_handlers_builder = ext
72 .initialize_shutdown_handlers(state.clone(), shutdown_handlers_builder)
73 .await;
74 permissions_builder = ext
75 .initialize_permissions(state.clone(), permissions_builder)
76 .await;
77 }
78
79 *state.mail.templates.templates.write() = email_templates_builder.finish();
80
81 crate::permissions::USER_PERMISSIONS
82 .write()
83 .replace(permissions_builder.user_permissions);
84 crate::permissions::ADMIN_PERMISSIONS
85 .write()
86 .replace(permissions_builder.admin_permissions);
87 crate::permissions::SERVER_PERMISSIONS
88 .write()
89 .replace(permissions_builder.server_permissions);
90
91 (
92 route_builder,
93 background_tasks_builder,
94 shutdown_handlers_builder,
95 )
96 }
97
98 pub async fn init_cli(
99 &self,
100 env: Option<&Arc<crate::env::Env>>,
101 mut builder: CliCommandGroupBuilder,
102 ) -> CliCommandGroupBuilder {
103 for ext in self.vec.write().await.iter_mut() {
104 let ext = match Arc::get_mut(&mut ext.extension) {
105 Some(ext) => ext,
106 None => {
107 panic!(
108 "Failed to get mutable reference to extension {}. This should NEVER happen.",
109 ext.package_name
110 );
111 }
112 };
113
114 builder = ext.initialize_cli(env, builder).await;
115 }
116
117 builder
118 }
119
120 #[inline]
121 pub async fn extensions(&self) -> RwLockReadGuard<'_, Vec<ConstructedExtension>> {
122 self.vec.read().await
123 }
124
125 #[inline]
126 pub fn blocking_extensions(&self) -> RwLockReadGuard<'_, Vec<ConstructedExtension>> {
127 self.vec.blocking_read()
128 }
129
130 pub async fn call(
131 &self,
132 name: impl AsRef<str>,
133 args: &[super::ExtensionCallValue],
134 ) -> Option<super::ExtensionCallValue> {
135 for ext in self.extensions().await.iter() {
136 if let Some(ret) = ext.process_call(name.as_ref(), args).await {
137 return Some(ret);
138 }
139 }
140
141 None
142 }
143}