devalang_core/core/plugin/
loader.rs1use std::path::Path;
2use serde::Deserialize;
3
4#[derive(Debug, Deserialize, Clone)]
5pub struct PluginInfo {
6 pub name: String,
7 pub version: Option<String>,
8 pub description: Option<String>,
9 pub author: Option<String>,
10}
11
12#[derive(Debug, Deserialize, Clone)]
13pub struct PluginFile {
14 pub plugin: PluginInfo,
15}
16
17pub fn load_plugin(name: &str) -> Result<(PluginInfo, Vec<u8>), String> {
18 let root = Path::new(env!("CARGO_MANIFEST_DIR"));
19 let plugin_dir = root.join(".deva").join("plugin").join(name);
20 let toml_path = plugin_dir.join("plugin.toml");
21 let wasm_path = plugin_dir.join(format!("{}_bg.wasm", name));
22
23 if !toml_path.exists() {
24 return Err(format!("❌ Plugin file not found: {}", toml_path.display()));
25 }
26 if !wasm_path.exists() {
27 return Err(format!("❌ Plugin wasm not found: {}", wasm_path.display()));
28 }
29
30 let toml_content = std::fs::read_to_string(&toml_path)
31 .map_err(|e| format!("Failed to read '{}': {}", toml_path.display(), e))?;
32 let plugin_file: PluginFile = toml::from_str(&toml_content)
33 .map_err(|e| format!("Failed to parse '{}': {}", toml_path.display(), e))?;
34
35 let wasm_bytes = std::fs::read(&wasm_path)
36 .map_err(|e| format!("Failed to read '{}': {}", wasm_path.display(), e))?;
37
38 Ok((plugin_file.plugin, wasm_bytes))
39}
40
41pub fn load_plugin_from_uri(uri: &str) -> Result<(PluginInfo, Vec<u8>), String> {
42 if !uri.starts_with("devalang://plugin/") {
43 return Err("Invalid plugin URI".into());
44 }
45
46 let name = uri.trim_start_matches("devalang://plugin/");
47 load_plugin(name)
48}