shared/extensions/
manager.rs

1use 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}