plux_rs/context/
loader_context.rs

1use std::sync::Arc;
2
3use crate::{
4    Info, Loader, Manager,
5    function::{Function, Request},
6    utils::RegisterManagerError,
7};
8
9/// Context for configuring the plugin loader.
10///
11/// LoaderContext provides a fluent interface for setting up the plugin loader with
12/// managers, functions, and requests. It ensures proper initialization order and
13/// provides convenient methods for loader configuration.
14///
15/// # Type Parameters
16///
17/// * `'a` - Lifetime for references within the loader
18/// * `'b` - Lifetime of the loader reference
19/// * `O` - Output type for plugin functions (must implement Send + Sync)
20/// * `I` - Plugin information type (must implement Info trait)
21///
22/// # Fields
23///
24/// * `loader` - Mutable reference to the underlying loader
25///
26/// # Example
27///
28/// ```rust,no_run,ignore
29/// use plux_rs::prelude::*;
30/// use plux_custom_manager::CustomManager;
31///
32/// #[plux_rs::function]
33/// fn my_function(_: ()) {
34///     // Function implementation
35/// }
36/// 
37/// let mut loader = Loader::new();
38/// loader.context(|mut ctx| {
39///     // Register a manager
40///     ctx.register_manager(CustomManager::new())?;
41///
42///     // Register functions and requests
43///     ctx.register_function(my_function());
44///     ctx.register_request(Request::new("main".to_string(), vec![], None));
45///
46///     Ok(())
47/// });
48/// ```
49pub struct LoaderContext<'a, 'b, O: Send + Sync, I: Info> {
50    loader: &'b mut Loader<'a, O, I>,
51}
52
53impl<'a, 'b, O: Send + Sync, I: Info> LoaderContext<'a, 'b, O, I> {
54    /// Creates a new loader context.
55    ///
56    /// This is an internal constructor used by the loader when creating contexts.
57    ///
58    /// # Parameters
59    ///
60    /// * `loader` - Mutable reference to the loader to configure
61    ///
62    /// # Returns
63    ///
64    /// Returns a new LoaderContext instance.
65    pub(crate) fn new(loader: &'b mut Loader<'a, O, I>) -> Self {
66        Self { loader }
67    }
68
69    /// Registers a plugin manager with the loader.
70    ///
71    /// This method registers a manager that can handle plugins of a specific format.
72    ///
73    /// # Parameters
74    ///
75    /// * `manager` - The manager instance to register
76    ///
77    /// # Returns
78    ///
79    /// Returns `Result<(), RegisterManagerError>` indicating success or failure.
80    ///
81    /// # Type Parameters
82    ///
83    /// * `M` - Type of the manager (must implement Manager trait)
84    pub fn register_manager<M>(&mut self, manager: M) -> Result<(), RegisterManagerError>
85    where
86        M: Manager<'a, O, I> + 'static,
87    {
88        self.loader.register_manager(manager)
89    }
90
91    /// Registers multiple plugin managers with the loader.
92    ///
93    /// This method registers a collection of managers in sequence.
94    ///
95    /// # Parameters
96    ///
97    /// * `managers` - Iterator of manager instances to register
98    ///
99    /// # Returns
100    ///
101    /// Returns `Result<(), RegisterManagerError>` indicating success or failure.
102    pub fn register_managers<M>(&mut self, managers: M) -> Result<(), RegisterManagerError>
103    where
104        M: IntoIterator<Item = Box<dyn Manager<'a, O, I>>>,
105    {
106        self.loader.register_managers(managers)
107    }
108
109    /// Registers a function request with the loader.
110    ///
111    /// Function requests define the interface that plugins must implement.
112    ///
113    /// # Parameters
114    ///
115    /// * `request` - The request to register
116    pub fn register_request(&mut self, request: Request) {
117        self.loader.requests.push(request);
118    }
119
120    /// Registers multiple function requests with the loader.
121    ///
122    /// This method registers a collection of requests.
123    ///
124    /// # Parameters
125    ///
126    /// * `requests` - Iterator of requests to register
127    ///
128    /// # Type Parameters
129    ///
130    /// * `IT` - Type of the iterator containing requests
131    pub fn register_requests<IT>(&mut self, requests: IT)
132    where
133        IT: IntoIterator<Item = Request>,
134    {
135        self.loader.requests.extend(requests);
136    }
137
138    /// Registers a function in the loader's registry.
139    ///
140    /// Functions registered here are available to all plugins.
141    ///
142    /// # Parameters
143    ///
144    /// * `function` - The function to register
145    ///
146    /// # Type Parameters
147    ///
148    /// * `F` - Type of the function (must implement Function trait)
149    pub fn register_function<F>(&mut self, function: F)
150    where
151        F: Function<Output = O> + 'static,
152    {
153        self.loader.registry.push(Arc::new(function));
154    }
155
156    /// Registers multiple functions in the loader's registry.
157    ///
158    /// This method registers a collection of functions.
159    ///
160    /// # Parameters
161    ///
162    /// * `functions` - Iterator of functions to register
163    ///
164    /// # Type Parameters
165    ///
166    /// * `F` - Type of the functions (must implement Function trait)
167    /// * `IT` - Type of the iterator containing functions
168    pub fn register_functions<F, IT>(&mut self, functions: IT)
169    where
170        F: Function<Output = O> + 'static,
171        IT: IntoIterator<Item = F>,
172    {
173        self.loader.registry.extend(
174            functions
175                .into_iter()
176                .map(|f| Arc::new(f) as Arc<dyn Function<Output = O>>),
177        );
178    }
179}