1use std::fs;
2use std::path::{Path, PathBuf};
3use std::sync::Arc;
4use crate::Plugin;
5use oxidite_core::Result;
6
7pub struct PluginLoader;
9
10impl PluginLoader {
11 pub fn new() -> Self {
12 Self
13 }
14
15 #[cfg(not(target_arch = "wasm32"))]
17 pub fn load_from_file<P: AsRef<Path>>(&self, _path: P) -> Result<Arc<dyn Plugin>> {
18 Err(oxidite_core::Error::InternalServerError(
21 "Plugin loading from file not implemented in this version".to_string()
22 ))
23 }
24
25 pub fn scan_directory<P: AsRef<Path>>(&self, path: P) -> Result<Vec<PathBuf>> {
27 let dir = path.as_ref();
28 if !dir.exists() {
29 return Ok(Vec::new());
30 }
31
32 let mut plugins = Vec::new();
33 for entry in fs::read_dir(dir)
34 .map_err(|e| oxidite_core::Error::InternalServerError(e.to_string()))?
35 {
36 let entry = entry
37 .map_err(|e| oxidite_core::Error::InternalServerError(e.to_string()))?;
38 let path = entry.path();
39
40 let is_plugin_file = path.extension()
41 .and_then(|e| e.to_str())
42 .map(|ext| matches!(ext, "so" | "dylib" | "dll"))
43 .unwrap_or(false);
44 if is_plugin_file {
45 plugins.push(path);
46 }
47 }
48
49 Ok(plugins)
50 }
51
52 pub async fn load_from_directory<P: AsRef<Path>>(&self, path: P) -> Result<Vec<Arc<dyn Plugin>>> {
54 println!("Scanning for plugins in: {:?}", path.as_ref());
55 let mut plugins = Vec::new();
56 for plugin_path in self.scan_directory(path)? {
57 match self.load_from_file(&plugin_path) {
58 Ok(plugin) => plugins.push(plugin),
59 Err(e) => {
60 eprintln!("Failed to load plugin {:?}: {}", plugin_path, e);
61 }
62 }
63 }
64 Ok(plugins)
65 }
66}
67
68#[cfg(test)]
69mod tests {
70 use super::*;
71 use crate::PluginInfo;
72
73 struct TestPlugin;
75
76 #[async_trait::async_trait]
77 impl Plugin for TestPlugin {
78 fn info(&self) -> PluginInfo {
79 PluginInfo::new(
80 "test-plugin",
81 "Test Plugin",
82 "1.0.0",
83 "A test plugin for Oxidite",
84 "Test Author"
85 )
86 }
87 }
88
89 #[test]
90 fn test_plugin_info() {
91 let plugin = TestPlugin;
92 let info = plugin.info();
93
94 assert_eq!(info.id, "test-plugin");
95 assert_eq!(info.name, "Test Plugin");
96 assert_eq!(info.version, "1.0.0");
97 }
98}