Skip to main content

palladium_plugin/
manifest.rs

1use std::path::PathBuf;
2
3use serde::Deserialize;
4
5use crate::error::PluginError;
6
7// ── PluginKind ────────────────────────────────────────────────────────────────
8
9/// Whether a plugin is a native shared library or a WASM module.
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
11#[serde(rename_all = "lowercase")]
12pub enum PluginKind {
13    /// Native shared library loaded via `dlopen` / `libloading`.
14    Native,
15    /// WebAssembly module loaded via `wasmtime`.
16    Wasm,
17}
18
19// ── PluginInfo ────────────────────────────────────────────────────────────────
20
21/// Runtime metadata for a loaded plugin, returned by [`PluginRegistry::list`].
22///
23/// [`PluginRegistry::list`]: crate::PluginRegistry::list
24#[derive(Debug, Clone, PartialEq, Eq)]
25pub struct PluginInfo {
26    /// Plugin name as declared in its manifest.
27    pub name: String,
28    /// Semantic version string (e.g. `"1.0.0"`).
29    pub version: String,
30    /// Whether this is a native or WASM plugin.
31    pub kind: PluginKind,
32    /// Number of actor types this plugin exports.
33    pub actor_type_count: usize,
34}
35
36// ── NamespacePolicyConfig ─────────────────────────────────────────────────────
37
38/// Namespace policy overrides declared in a plugin manifest.
39///
40/// By default, plugin actors may only address actors within their own
41/// namespace (`/plugins/<name>/`) and `/system/`. This struct lets a manifest
42/// grant additional visibility or explicit denials.
43#[derive(Debug, Clone, Deserialize)]
44pub struct NamespacePolicyConfig {
45    /// Additional namespaces plugin actors may send to.
46    pub visible: Option<Vec<String>>,
47    /// Namespaces plugin actors are explicitly denied access to.
48    pub denied: Option<Vec<String>>,
49}
50
51// ── PluginManifest ────────────────────────────────────────────────────────────
52
53/// Parsed plugin manifest (`plugin.toml`).
54///
55/// Every plugin ships a `plugin.toml` alongside its shared library or WASM
56/// file. The engine reads this manifest at load time to verify the ABI,
57/// determine the library path, and configure namespace isolation.
58///
59/// # Example
60///
61/// ```toml
62/// name    = "echo"
63/// version = "1.0.0"
64/// kind    = "native"
65/// library = "target/debug/libecho.dylib"
66///
67/// [namespace]
68/// visible = ["/plugins/logger"]
69/// ```
70#[derive(Debug, Clone, Deserialize)]
71pub struct PluginManifest {
72    /// Plugin name — must be unique within the engine.
73    pub name: String,
74    /// Semantic version string.
75    pub version: String,
76    /// Plugin kind: `"native"` or `"wasm"`.
77    pub kind: PluginKind,
78    /// Path to the shared library or WASM file, relative to the manifest.
79    pub library: PathBuf,
80    /// Optional namespace policy overrides.
81    pub namespace: Option<NamespacePolicyConfig>,
82}
83
84impl PluginManifest {
85    /// Parse a `plugin.toml` from a TOML string.
86    ///
87    /// Returns `Err(PluginError::LoadFailed(...))` if the TOML is malformed or
88    /// missing required fields.
89    pub fn from_toml(s: &str) -> Result<Self, PluginError> {
90        toml::from_str(s).map_err(|e| PluginError::LoadFailed(e.to_string()))
91    }
92}