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}