Skip to main content

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