Skip to main content

malbox_plugin_sdk/
meta.rs

1//! Plugin metadata: identity, lifecycle behavior, and concurrency model.
2//!
3//! These types describe a plugin to the daemon. [`PluginMeta`] carries
4//! the identity fields (name, version, etc.) while [`PluginState`] and
5//! [`ExecutionContext`] control how the daemon manages the plugin's lifetime
6//! and task scheduling.
7
8/// Metadata about a plugin.
9///
10/// Constructed via the builder pattern: [`PluginMeta::new`] followed by
11/// optional chained setters. Generic fields (`name`, `version`, `description`,
12/// `authors`) are sourced automatically from `Cargo.toml` via `env!()` macros
13/// so that plugin authors don't have to duplicate them.
14#[derive(Debug, Clone, PartialEq)]
15pub struct PluginMeta {
16    name: String,
17    version: String,
18    description: String,
19    authors: String,
20    state: PluginState,
21    execution: ExecutionContext,
22}
23
24impl PluginMeta {
25    /// Create metadata with a plugin name and version. All other fields
26    /// start at sensible defaults (ephemeral state, exclusive execution).
27    pub fn new(name: impl Into<String>, version: impl Into<String>) -> Self {
28        Self {
29            name: name.into(),
30            version: version.into(),
31            description: String::new(),
32            authors: String::new(),
33            state: PluginState::Ephemeral,
34            execution: ExecutionContext::Exclusive,
35        }
36    }
37
38    /// Set a human-readable description of what the plugin does.
39    pub fn with_description(mut self, d: impl Into<String>) -> Self {
40        self.description = d.into();
41        self
42    }
43
44    /// Set the plugin author(s), typically sourced from `Cargo.toml`.
45    pub fn with_authors(mut self, a: impl Into<String>) -> Self {
46        self.authors = a.into();
47        self
48    }
49
50    /// Set the plugin's lifecycle behavior (persistent, ephemeral, or scoped).
51    pub fn with_state(mut self, s: PluginState) -> Self {
52        self.state = s;
53        self
54    }
55
56    /// Set the concurrency model the daemon should use when dispatching tasks.
57    pub fn with_execution(mut self, e: ExecutionContext) -> Self {
58        self.execution = e;
59        self
60    }
61
62    /// The plugin's unique identifier (typically the crate name).
63    pub fn name(&self) -> &str {
64        &self.name
65    }
66
67    /// The plugin's version string (typically from `Cargo.toml`).
68    pub fn version(&self) -> &str {
69        &self.version
70    }
71
72    /// A short description of what the plugin does. May be empty.
73    pub fn description(&self) -> &str {
74        &self.description
75    }
76
77    /// The plugin author(s). May be empty.
78    pub fn authors(&self) -> &str {
79        &self.authors
80    }
81
82    /// How the daemon manages this plugin's lifetime between tasks.
83    pub fn state(&self) -> PluginState {
84        self.state
85    }
86
87    /// How the daemon schedules concurrent tasks for this plugin.
88    pub fn execution(&self) -> ExecutionContext {
89        self.execution
90    }
91}
92
93/// Lifecycle behavior of the plugin.
94#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
95pub enum PluginState {
96    /// Stays running between tasks.
97    Persistent,
98    /// Spun up per task and torn down immediately after.
99    Ephemeral,
100    /// Lives for the duration of an analysis scope (e.g. a batch).
101    Scoped,
102}
103
104/// Concurrency model for task execution.
105#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
106pub enum ExecutionContext {
107    /// Only one instance runs at a time across the entire daemon.
108    Exclusive,
109    /// Tasks are dispatched one at a time in order.
110    Sequential,
111    /// Multiple tasks may run concurrently.
112    Parallel,
113    /// No constraints on concurrency or ordering.
114    Unrestricted,
115}