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 background_tasks_builder =
32 super::background_tasks::BackgroundTaskBuilder::new(state.clone());
33 let mut shutdown_handlers_builder =
34 super::shutdown_handlers::ShutdownHandlerBuilder::new(state.clone());
35 let mut permissions_builder = ExtensionPermissionsBuilder::new(
36 crate::permissions::BASE_USER_PERMISSIONS.clone(),
37 crate::permissions::BASE_ADMIN_PERMISSIONS.clone(),
38 crate::permissions::BASE_SERVER_PERMISSIONS.clone(),
39 );
40
41 for ext in self.vec.read().await.iter() {
42 let deserializer = ext.settings_deserializer(state.clone()).await;
43 crate::settings::SETTINGS_DESER_EXTENSIONS
44 .write()
45 .unwrap()
46 .insert(ext.package_name, deserializer);
47 }
48 state.settings.invalidate_cache().await;
49
50 for ext in self.vec.write().await.iter_mut() {
51 let ext = match Arc::get_mut(&mut ext.extension) {
52 Some(ext) => ext,
53 None => {
54 panic!(
55 "Failed to get mutable reference to extension {}. This should NEVER happen.",
56 ext.package_name
57 );
58 }
59 };
60
61 ext.initialize(state.clone()).await;
62
63 route_builder = ext.initialize_router(state.clone(), route_builder).await;
64 background_tasks_builder = ext
65 .initialize_background_tasks(state.clone(), background_tasks_builder)
66 .await;
67 shutdown_handlers_builder = ext
68 .initialize_shutdown_handlers(state.clone(), shutdown_handlers_builder)
69 .await;
70 permissions_builder = ext
71 .initialize_permissions(state.clone(), permissions_builder)
72 .await;
73 }
74
75 crate::permissions::USER_PERMISSIONS
76 .write()
77 .unwrap()
78 .replace(permissions_builder.user_permissions);
79 crate::permissions::ADMIN_PERMISSIONS
80 .write()
81 .unwrap()
82 .replace(permissions_builder.admin_permissions);
83 crate::permissions::SERVER_PERMISSIONS
84 .write()
85 .unwrap()
86 .replace(permissions_builder.server_permissions);
87
88 (
89 route_builder,
90 background_tasks_builder,
91 shutdown_handlers_builder,
92 )
93 }
94
95 pub async fn init_cli(
96 &self,
97 env: Option<&Arc<crate::env::Env>>,
98 mut builder: CliCommandGroupBuilder,
99 ) -> CliCommandGroupBuilder {
100 for ext in self.vec.write().await.iter_mut() {
101 let ext = match Arc::get_mut(&mut ext.extension) {
102 Some(ext) => ext,
103 None => {
104 panic!(
105 "Failed to get mutable reference to extension {}. This should NEVER happen.",
106 ext.package_name
107 );
108 }
109 };
110
111 builder = ext.initialize_cli(env, builder).await;
112 }
113
114 builder
115 }
116
117 #[inline]
118 pub async fn extensions(&self) -> RwLockReadGuard<'_, Vec<ConstructedExtension>> {
119 self.vec.read().await
120 }
121
122 pub async fn call(
123 &self,
124 name: impl AsRef<str>,
125 args: &[super::ExtensionCallValue],
126 ) -> Option<super::ExtensionCallValue> {
127 for ext in self.extensions().await.iter() {
128 if let Some(ret) = ext.process_call(name.as_ref(), args).await {
129 return Some(ret);
130 }
131 }
132
133 None
134 }
135}