plux_rs/
manager.rs

1use crate::{
2    Api, Info, Plugin, RegisterPluginContext, context::LoadPluginContext, utils::ManagerResult,
3};
4
5/// Trait for implementing custom plugin managers.
6///
7/// A plugin manager is responsible for handling plugins of a specific format (e.g., Lua, Rust, WASM).
8/// It provides the interface between the Plux engine and the actual plugin execution environment.
9///
10/// # Type Parameters
11///
12/// * `'a` - Lifetime parameter for references within the manager
13/// * `O` - Output type for plugin functions (must implement Send + Sync)
14/// * `I` - Plugin information type (must implement Info trait)
15///
16/// # Example
17///
18/// ```rust,no_run
19/// use plux_rs::{Manager, LoadPluginContext, RegisterPluginContext, Api, Plugin, StdInfo, utils::ManagerResult, function::FunctionOutput};
20///
21/// struct MyManager;
22///
23/// impl<'a> Manager<'a, FunctionOutput, StdInfo> for MyManager {
24///     fn format(&self) -> &'static str {
25///         "my_format"
26///     }
27///
28///     fn register_plugin(&mut self, context: RegisterPluginContext) -> ManagerResult<StdInfo> {
29///         // Implementation for registering a plugin
30///         Ok(StdInfo {
31///             depends: vec![],
32///             optional_depends: vec![],
33///         })
34///     }
35/// }
36/// ```
37pub trait Manager<'a, O: Send + Sync, I: Info>: Send + Sync {
38    /// Returns the file format/extension this manager handles (e.g., "lua", "rs", "wasm").
39    ///
40    /// This format is used to identify which manager should handle a particular plugin file.
41    fn format(&self) -> &'static str;
42
43    /// Called when the manager is registered with the loader.
44    ///
45    /// This is the place to perform any initialization required by the manager.
46    /// Default implementation does nothing and returns Ok(()).
47    ///
48    /// # Returns
49    ///
50    /// Returns `ManagerResult<()>` indicating success or failure of manager registration.
51    fn register_manager(&mut self) -> ManagerResult<()> {
52        Ok(())
53    }
54
55    /// Called when the manager is unregistered from the loader.
56    ///
57    /// This is the place to perform any cleanup required by the manager.
58    /// Default implementation does nothing and returns Ok(()).
59    ///
60    /// # Returns
61    ///
62    /// Returns `ManagerResult<()>` indicating success or failure of manager unregistration.
63    fn unregister_manager(&mut self) -> ManagerResult<()> {
64        Ok(())
65    }
66
67    /// Registers a plugin with this manager.
68    ///
69    /// This method is called when a plugin file matching this manager's format is discovered.
70    /// The manager should validate the plugin and return information about it.
71    ///
72    /// # Parameters
73    ///
74    /// * `context` - Context containing plugin path and bundle information
75    ///
76    /// # Returns
77    ///
78    /// Returns `ManagerResult<I>` containing plugin information on success.
79    fn register_plugin(&mut self, _context: RegisterPluginContext) -> ManagerResult<I>;
80
81    /// Unregisters a plugin from this manager.
82    ///
83    /// This method is called when a plugin is being removed from the system.
84    /// Default implementation does nothing and returns Ok(()).
85    ///
86    /// # Parameters
87    ///
88    /// * `plugin` - Reference to the plugin being unregistered
89    ///
90    /// # Returns
91    ///
92    /// Returns `ManagerResult<()>` indicating success or failure of plugin unregistration.
93    fn unregister_plugin(&mut self, _plugin: &Plugin<'a, O, I>) -> ManagerResult<()> {
94        Ok(())
95    }
96
97    /// Loads a plugin into the execution environment.
98    ///
99    /// This method is called after plugin registration and is responsible for making the plugin
100    /// available for execution. This typically involves loading the plugin code, registering
101    /// functions, and setting up the execution context.
102    ///
103    /// Default implementation does nothing and returns Ok(()).
104    ///
105    /// # Parameters
106    ///
107    /// * `context` - Context containing plugin and loader information
108    /// * `api` - API interface for interacting with the host application
109    ///
110    /// # Returns
111    ///
112    /// Returns `ManagerResult<()>` indicating success or failure of plugin loading.
113    fn load_plugin(
114        &mut self,
115        _context: LoadPluginContext<'a, '_, O, I>,
116        _api: Api<O, I>,
117    ) -> ManagerResult<()> {
118        Ok(())
119    }
120
121    /// Unloads a plugin from the execution environment.
122    ///
123    /// This method is called when a plugin is being unloaded. It should clean up any resources
124    /// associated with the plugin.
125    ///
126    /// Default implementation does nothing and returns Ok(()).
127    ///
128    /// # Parameters
129    ///
130    /// * `plugin` - Reference to the plugin being unloaded
131    ///
132    /// # Returns
133    ///
134    /// Returns `ManagerResult<()>` indicating success or failure of plugin unloading.
135    fn unload_plugin(&mut self, _plugin: &Plugin<'a, O, I>) -> ManagerResult<()> {
136        Ok(())
137    }
138}
139
140impl<'a, O: Send + Sync, I: Info> PartialEq for dyn Manager<'a, O, I> {
141    fn eq(&self, other: &Self) -> bool {
142        self.format() == other.format()
143    }
144}
145
146impl<'a, O, OO, I, II> PartialEq<Box<dyn Manager<'a, O, I>>> for dyn Manager<'a, OO, II>
147where
148    O: Send + Sync,
149    OO: Send + Sync,
150    I: Info,
151    II: Info,
152{
153    fn eq(&self, other: &Box<dyn Manager<'a, O, I>>) -> bool {
154        self.format() == other.format()
155    }
156}
157
158impl<'a, O, OO, I, II> PartialEq<dyn Manager<'a, OO, II>> for Box<dyn Manager<'a, O, I>>
159where
160    O: Send + Sync,
161    OO: Send + Sync,
162    I: Info,
163    II: Info,
164{
165    fn eq(&self, other: &dyn Manager<'a, OO, II>) -> bool {
166        self.format() == other.format()
167    }
168}