oxidite_plugin/
manager.rs1use std::collections::HashMap;
2use std::path::Path;
3use std::sync::Arc;
4use oxidite_core::{Result, Error};
5
6use crate::{Plugin, PluginInfo, PluginHook, HookResult, PluginLoader, PluginConfig};
7
8pub struct PluginManager {
10 plugins: HashMap<String, Arc<dyn Plugin>>,
11 config: PluginConfig,
12}
13
14impl PluginManager {
15 pub fn new(config: PluginConfig) -> Self {
16 Self {
17 plugins: HashMap::new(),
18 config,
19 }
20 }
21
22 pub async fn load_plugins_from_directory<P: AsRef<Path>>(&mut self, path: P) -> Result<()> {
24 let loader = PluginLoader::new();
25 let loaded_plugins = loader.load_from_directory(path).await?;
26 for plugin in loaded_plugins {
27 self.register_plugin(plugin)?;
28 }
29
30 if self.config.enabled_plugins.is_empty() {
31 return Ok(());
32 }
33
34 for plugin_id in self.config.enabled_plugins.clone() {
35 let _ = self.enable_plugin(&plugin_id).await;
36 }
37 Ok(())
38 }
39
40 pub fn register_plugin(&mut self, plugin: Arc<dyn Plugin>) -> Result<()> {
42 let info = plugin.info();
43
44 if self.plugins.contains_key(&info.id) {
45 return Err(Error::InternalServerError(
46 format!("Plugin with id '{}' already exists", info.id)
47 ));
48 }
49
50 self.plugins.insert(info.id.clone(), plugin);
51
52 Ok(())
53 }
54
55 pub async fn enable_plugin(&mut self, plugin_id: &str) -> Result<()> {
57 if let Some(plugin) = self.plugins.get(plugin_id) {
58 plugin.on_enable().await?;
59
60 Ok(())
64 } else {
65 Err(Error::NotFound(format!("Plugin '{}' not found", plugin_id)))
66 }
67 }
68
69 pub async fn disable_plugin(&mut self, plugin_id: &str) -> Result<()> {
71 if let Some(plugin) = self.plugins.get(plugin_id) {
72 plugin.on_disable().await?;
73 Ok(())
74 } else {
75 Err(Error::NotFound(format!("Plugin '{}' not found", plugin_id)))
76 }
77 }
78
79 pub async fn execute_hook(&self, hook: PluginHook) -> Result<HookResult> {
81 let mut result = HookResult::Continue;
82
83 for plugin in self.plugins.values() {
84 if !plugin.info().enabled {
85 continue;
86 }
87
88 result = plugin.hook(hook.clone()).await;
89
90 match result {
91 HookResult::Stop => break,
92 HookResult::Response(_) => return Ok(result),
93 HookResult::Error(_) => return Ok(result),
94 _ => continue,
95 }
96 }
97
98 Ok(result)
99 }
100
101 pub fn list_plugins(&self) -> Vec<PluginInfo> {
103 self.plugins.values()
104 .map(|p| p.info())
105 .collect()
106 }
107
108 pub async fn initialize(&self) -> Result<()> {
110 for plugin in self.plugins.values() {
111 if plugin.info().enabled {
112 plugin.on_load().await?;
113 }
114 }
115
116 Ok(())
117 }
118
119 pub async fn shutdown(&self) -> Result<()> {
121 for plugin in self.plugins.values() {
122 plugin.on_unload().await?;
123 }
124
125 Ok(())
126 }
127}
128
129pub fn create_manager(config: PluginConfig) -> PluginManager {
131 PluginManager::new(config)
132}