plux_rs/api.rs
1use rayon::prelude::IntoParallelIterator;
2use semver::Version;
3
4use crate::{
5 Bundle, Info, Loader, Manager, Plugin, Registry, Requests,
6 utils::{
7 CallFunctionDependError, LoadPluginError, PluginCallFunctionError, PluginCallRequestError,
8 PluginOperationError, Ptr, RegisterManagerError, RegisterPluginError, UnloadPluginError,
9 UnregisterManagerError, UnregisterPluginError,
10 },
11 variable::Variable,
12};
13
14/// API interface provided to plugins during loading.
15///
16/// The Api struct provides a controlled interface for plugins to interact with the Plux system.
17/// It allows plugins to access the loader's functionality while maintaining security boundaries
18/// and providing dependency-aware operations.
19///
20/// # Type Parameters
21///
22/// * `O` - Output type for plugin functions (must implement Send + Sync + 'static)
23/// * `I` - Plugin information type (must implement Info + 'static)
24///
25/// # Fields
26///
27/// * `loader` - Reference to the underlying loader
28/// * `plugin` - Bundle information for the current plugin
29/// * `depends` - List of required dependencies for this plugin
30/// * `optional_depends` - List of optional dependencies for this plugin
31pub struct Api<O: Send + Sync + 'static, I: Info + 'static> {
32 loader: Ptr<'static, Loader<'static, O, I>>,
33 plugin: Bundle,
34 depends: Vec<Bundle>,
35 optional_depends: Vec<Bundle>,
36}
37
38impl<O: Send + Sync + 'static, I: Info + 'static> Api<O, I> {
39 /// Creates a new API instance for a plugin.
40 ///
41 /// This is an internal constructor used by the loader when loading plugins.
42 ///
43 /// # Parameters
44 ///
45 /// * `loader` - Reference to the loader
46 /// * `plugin` - Bundle information for the plugin
47 /// * `depends` - Required dependencies
48 /// * `optional_depends` - Optional dependencies
49 ///
50 /// # Returns
51 ///
52 /// Returns a new Api instance.
53 pub(crate) const fn new(
54 loader: Ptr<'static, Loader<'static, O, I>>,
55 plugin: Bundle,
56 depends: Vec<Bundle>,
57 optional_depends: Vec<Bundle>,
58 ) -> Self {
59 Self {
60 loader,
61 plugin,
62 depends,
63 optional_depends,
64 }
65 }
66
67 /// Gets access to the function registry.
68 ///
69 /// Returns a reference to the registry containing all functions available to plugins.
70 ///
71 /// # Returns
72 ///
73 /// Returns `&Registry<O>` containing the function registry.
74 pub fn registry(&self) -> &Registry<O> {
75 &self.loader.as_ref().registry
76 }
77
78 /// Gets information about the current plugin.
79 ///
80 /// Returns the bundle information for the plugin this API instance belongs to.
81 ///
82 /// # Returns
83 ///
84 /// Returns `&Bundle` containing plugin metadata.
85 pub const fn plugin(&self) -> &Bundle {
86 &self.plugin
87 }
88
89 /// Gets the list of required dependencies.
90 ///
91 /// Returns all dependencies that must be available for this plugin to function.
92 ///
93 /// # Returns
94 ///
95 /// Returns `&Vec<Bundle>` containing required dependencies.
96 pub const fn depends(&self) -> &Vec<Bundle> {
97 &self.depends
98 }
99
100 /// Gets the list of optional dependencies.
101 ///
102 /// Returns all optional dependencies that enhance this plugin's functionality but are not required.
103 ///
104 /// # Returns
105 ///
106 /// Returns `&Vec<Bundle>` containing optional dependencies.
107 pub const fn optional_depends(&self) -> &Vec<Bundle> {
108 &self.optional_depends
109 }
110
111 // Loader functions
112
113 /// Registers a plugin manager with the loader.
114 ///
115 /// This method allows plugins to register new managers during execution.
116 ///
117 /// # Parameters
118 ///
119 /// * `manager` - The manager instance to register
120 ///
121 /// # Returns
122 ///
123 /// Returns `Result<(), RegisterManagerError>` indicating success or failure.
124 ///
125 /// # Type Parameters
126 ///
127 /// * `M` - Type of the manager (must implement Manager trait)
128 pub fn register_manager<M>(&self, manager: M) -> Result<(), RegisterManagerError>
129 where
130 M: Manager<'static, O, I> + 'static,
131 {
132 self.loader.as_mut().register_manager(manager)
133 }
134
135 /// Registers multiple plugin managers with the loader.
136 ///
137 /// This method allows plugins to register multiple managers in sequence.
138 ///
139 /// # Parameters
140 ///
141 /// * `managers` - Iterator of manager instances to register
142 ///
143 /// # Returns
144 ///
145 /// Returns `Result<(), RegisterManagerError>` indicating success or failure.
146 pub fn register_managers<M>(&self, managers: M) -> Result<(), RegisterManagerError>
147 where
148 M: IntoIterator<Item = Box<dyn Manager<'static, O, I>>>,
149 {
150 self.loader.as_mut().register_managers(managers)
151 }
152
153 /// Registers multiple plugin managers with the loader in parallel.
154 ///
155 /// This method allows plugins to register multiple managers concurrently.
156 ///
157 /// # Parameters
158 ///
159 /// * `managers` - Parallel iterator of manager instances to register
160 ///
161 /// # Returns
162 ///
163 /// Returns `Result<(), RegisterManagerError>` indicating success or failure.
164 pub fn par_register_managers<M>(&self, managers: M) -> Result<(), RegisterManagerError>
165 where
166 M: IntoParallelIterator<Item = Box<dyn Manager<'static, O, I>>>,
167 {
168 self.loader.as_mut().par_register_managers(managers)
169 }
170
171 /// Unregisters a plugin manager from the loader.
172 ///
173 /// This method allows plugins to unregister managers by format.
174 ///
175 /// # Parameters
176 ///
177 /// * `format` - The format of the manager to unregister
178 ///
179 /// # Returns
180 ///
181 /// Returns `Result<(), UnregisterManagerError>` indicating success or failure.
182 pub fn unregister_manager(&self, format: &str) -> Result<(), UnregisterManagerError> {
183 self.loader.as_mut().unregister_manager(format)
184 }
185
186 /// Gets an immutable reference to a manager by format.
187 ///
188 /// This method allows plugins to access registered managers.
189 ///
190 /// # Parameters
191 ///
192 /// * `format` - The format of the manager to retrieve
193 ///
194 /// # Returns
195 ///
196 /// Returns `Option<&Box<dyn Manager<'static, O, I>>>` containing the manager if found.
197 pub fn get_manager_ref(&self, format: &str) -> Option<&Box<dyn Manager<'static, O, I>>> {
198 self.loader.as_ref().get_manager_ref(format)
199 }
200
201 /// Gets an immutable reference to a manager by format (parallel version).
202 ///
203 /// This method allows plugins to access registered managers using parallel processing.
204 ///
205 /// # Parameters
206 ///
207 /// * `format` - The format of the manager to retrieve
208 ///
209 /// # Returns
210 ///
211 /// Returns `Option<&Box<dyn Manager<'static, O, I>>>` containing the manager if found.
212 pub fn par_get_manager_ref(&self, format: &str) -> Option<&Box<dyn Manager<'static, O, I>>> {
213 self.loader.as_ref().par_get_manager_ref(format)
214 }
215
216 /// Gets a mutable reference to a manager by format.
217 ///
218 /// This method allows plugins to access registered managers for modification.
219 ///
220 /// # Parameters
221 ///
222 /// * `format` - The format of the manager to retrieve
223 ///
224 /// # Returns
225 ///
226 /// Returns `Option<&mut Box<dyn Manager<'static, O, I>>>` containing the manager if found.
227 pub fn get_manager_mut(&self, format: &str) -> Option<&mut Box<dyn Manager<'static, O, I>>> {
228 self.loader.as_mut().get_manager_mut(format)
229 }
230
231 /// Gets a mutable reference to a manager by format (parallel version).
232 ///
233 /// This method allows plugins to access registered managers for modification using parallel processing.
234 ///
235 /// # Parameters
236 ///
237 /// * `format` - The format of the manager to retrieve
238 ///
239 /// # Returns
240 ///
241 /// Returns `Option<&mut Box<dyn Manager<'static, O, I>>>` containing the manager if found.
242 pub fn par_get_manager_mut(
243 &self,
244 format: &str,
245 ) -> Option<&mut Box<dyn Manager<'static, O, I>>> {
246 self.loader.as_mut().par_get_manager_mut(format)
247 }
248
249 /// Registers a plugin with the loader.
250 ///
251 /// This method allows plugins to register new plugins during execution.
252 ///
253 /// # Parameters
254 ///
255 /// * `path` - Path to the plugin file or directory
256 ///
257 /// # Returns
258 ///
259 /// Returns `Result<Bundle, RegisterPluginError>` containing the plugin bundle on success.
260 pub fn register_plugin(&self, path: &str) -> Result<Bundle, RegisterPluginError> {
261 self.loader.as_mut().register_plugin(path)
262 }
263
264 /// Registers multiple plugins with the loader.
265 ///
266 /// This method allows plugins to register multiple plugins in sequence.
267 ///
268 /// # Parameters
269 ///
270 /// * `paths` - Iterator of paths to plugin files or directories
271 ///
272 /// # Returns
273 ///
274 /// Returns `Result<Vec<Bundle>, RegisterPluginError>` containing the plugin bundles on success.
275 ///
276 /// # Type Parameters
277 ///
278 /// * `'b` - Lifetime of the path references
279 /// * `P` - Type of the iterator containing path references
280 pub fn register_plugins<'b, P>(&self, paths: P) -> Result<Vec<Bundle>, RegisterPluginError>
281 where
282 P: IntoIterator<Item = &'b str>,
283 {
284 self.loader.as_mut().register_plugins(paths)
285 }
286
287 /// Registers multiple plugins with the loader in parallel.
288 ///
289 /// This method allows plugins to register multiple plugins concurrently.
290 ///
291 /// # Parameters
292 ///
293 /// * `paths` - Parallel iterator of paths to plugin files or directories
294 ///
295 /// # Returns
296 ///
297 /// Returns `Result<Vec<Bundle>, RegisterPluginError>` containing the plugin bundles on success.
298 ///
299 /// # Type Parameters
300 ///
301 /// * `'b` - Lifetime of the path references
302 /// * `P` - Type of the parallel iterator containing path references
303 pub fn par_register_plugins<'b, P>(&self, paths: P) -> Result<Vec<Bundle>, RegisterPluginError>
304 where
305 P: IntoParallelIterator<Item = &'b str>,
306 {
307 self.loader.as_mut().par_register_plugins(paths)
308 }
309
310 /// Unregisters a plugin from the loader.
311 ///
312 /// This method allows plugins to unregister plugins by ID and version.
313 ///
314 /// # Parameters
315 ///
316 /// * `id` - Plugin identifier
317 /// * `version` - Plugin version
318 ///
319 /// # Returns
320 ///
321 /// Returns `Result<(), UnregisterPluginError>` indicating success or failure.
322 pub fn unregister_plugin(
323 &self,
324 id: &str,
325 version: &Version,
326 ) -> Result<(), UnregisterPluginError> {
327 self.loader.as_mut().unregister_plugin(id, version)
328 }
329
330 /// Unregisters a plugin from the loader by bundle.
331 ///
332 /// This method allows plugins to unregister plugins by bundle information.
333 ///
334 /// # Parameters
335 ///
336 /// * `bundle` - Plugin bundle information
337 ///
338 /// # Returns
339 ///
340 /// Returns `Result<(), UnregisterPluginError>` indicating success or failure.
341 pub fn unregister_plugin_by_bundle(
342 &self,
343 bundle: &Bundle,
344 ) -> Result<(), UnregisterPluginError> {
345 self.loader.as_mut().unregister_plugin_by_bundle(bundle)
346 }
347
348 /// Unregisters a plugin from the loader by bundle (parallel version).
349 ///
350 /// This method allows plugins to unregister plugins by bundle information using parallel processing.
351 ///
352 /// # Parameters
353 ///
354 /// * `bundle` - Plugin bundle information
355 ///
356 /// # Returns
357 ///
358 /// Returns `Result<(), UnregisterPluginError>` indicating success or failure.
359 pub fn par_unregister_plugin_by_bundle(
360 &self,
361 bundle: &Bundle,
362 ) -> Result<(), UnregisterPluginError> {
363 self.loader.as_mut().par_unregister_plugin_by_bundle(bundle)
364 }
365
366 /// Loads a plugin into the execution environment.
367 ///
368 /// This method allows plugins to load other plugins by ID and version.
369 ///
370 /// # Parameters
371 ///
372 /// * `id` - Plugin identifier
373 /// * `version` - Plugin version
374 ///
375 /// # Returns
376 ///
377 /// Returns `Result<(), LoadPluginError>` indicating success or failure.
378 pub fn load_plugin(&self, id: &str, version: &Version) -> Result<(), LoadPluginError> {
379 self.loader.as_mut().load_plugin(id, version)
380 }
381
382 /// Loads a plugin into the execution environment (parallel version).
383 ///
384 /// This method allows plugins to load other plugins by ID and version using parallel processing.
385 ///
386 /// # Parameters
387 ///
388 /// * `id` - Plugin identifier
389 /// * `version` - Plugin version
390 ///
391 /// # Returns
392 ///
393 /// Returns `Result<(), LoadPluginError>` indicating success or failure.
394 pub fn par_load_plugin(&self, id: &str, version: &Version) -> Result<(), LoadPluginError> {
395 self.loader.as_mut().par_load_plugin(id, version)
396 }
397
398 /// Loads a plugin into the execution environment by bundle.
399 ///
400 /// This method allows plugins to load other plugins by bundle information.
401 ///
402 /// # Parameters
403 ///
404 /// * `bundle` - Plugin bundle information
405 ///
406 /// # Returns
407 ///
408 /// Returns `Result<(), LoadPluginError>` indicating success or failure.
409 pub fn load_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), LoadPluginError> {
410 self.loader.as_mut().load_plugin_by_bundle(bundle)
411 }
412
413 /// Loads a plugin into the execution environment by bundle (parallel version).
414 ///
415 /// This method allows plugins to load other plugins by bundle information using parallel processing.
416 ///
417 /// # Parameters
418 ///
419 /// * `bundle` - Plugin bundle information
420 ///
421 /// # Returns
422 ///
423 /// Returns `Result<(), LoadPluginError>` indicating success or failure.
424 pub fn par_load_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), LoadPluginError> {
425 self.loader.as_mut().par_load_plugin_by_bundle(bundle)
426 }
427
428 /// Loads a plugin immediately from the specified path.
429 ///
430 /// This convenience method allows plugins to register and load a plugin in a single operation.
431 ///
432 /// # Parameters
433 ///
434 /// * `path` - Path to the plugin file or directory
435 ///
436 /// # Returns
437 ///
438 /// Returns `Result<Bundle, PluginOperationError>`
439 /// containing the plugin bundle on success, or errors from registration or loading.
440 pub fn load_plugin_now(&self, path: &str) -> Result<Bundle, PluginOperationError> {
441 self.loader.as_mut().load_plugin_now(path)
442 }
443
444 /// Loads multiple plugins from the specified paths.
445 ///
446 /// This method allows plugins to register and load multiple plugins in sequence.
447 ///
448 /// # Parameters
449 ///
450 /// * `paths` - Iterator of paths to plugin files or directories
451 ///
452 /// # Returns
453 ///
454 /// Returns `Result<Vec<Bundle>, PluginOperationError>`
455 /// containing the plugin bundles on success, or errors from registration or loading.
456 ///
457 /// # Type Parameters
458 ///
459 /// * `'b` - Lifetime of the path references
460 /// * `P` - Type of the iterator containing path references
461 pub fn load_plugins<'b, P>(&self, paths: P) -> Result<Vec<Bundle>, PluginOperationError>
462 where
463 P: IntoIterator<Item = &'b str>,
464 {
465 self.loader.as_mut().load_plugins(paths)
466 }
467
468 /// Loads multiple plugins from the specified paths (parallel version).
469 ///
470 /// This method allows plugins to register and load multiple plugins concurrently.
471 ///
472 /// # Parameters
473 ///
474 /// * `paths` - Parallel iterator of paths to plugin files or directories
475 ///
476 /// # Returns
477 ///
478 /// Returns `Result<Vec<Bundle>, PluginOperationError>`
479 /// containing the plugin bundles on success, or errors from registration or loading.
480 ///
481 /// # Type Parameters
482 ///
483 /// * `'b` - Lifetime of the path references
484 /// * `P` - Type of the parallel iterator containing path references
485 pub fn par_load_plugins<'b, P>(&self, paths: P) -> Result<Vec<Bundle>, PluginOperationError>
486 where
487 P: IntoParallelIterator<Item = &'b str>,
488 {
489 self.loader.as_mut().par_load_plugins(paths)
490 }
491
492 /// Loads only the plugins that are used (not dependencies of other plugins).
493 ///
494 /// This method allows plugins to register and load only the plugins that are not
495 /// dependencies of other plugins, and automatically unregisters unused plugins.
496 ///
497 /// # Parameters
498 ///
499 /// * `paths` - Iterator of paths to plugin files or directories
500 ///
501 /// # Returns
502 ///
503 /// Returns `Result<Vec<Bundle>, PluginOperationError>`
504 /// containing the plugin bundles on success, or errors from registration, unregistration, or loading.
505 ///
506 /// # Type Parameters
507 ///
508 /// * `'b` - Lifetime of the path references
509 /// * `P` - Type of the iterator containing path references
510 pub fn load_only_used_plugins<'b, P>(
511 &self,
512 paths: P,
513 ) -> Result<Vec<Bundle>, PluginOperationError>
514 where
515 P: IntoIterator<Item = &'b str>,
516 {
517 self.loader.as_mut().load_only_used_plugins(paths)
518 }
519
520 /// Loads only the plugins that are used (not dependencies of other plugins) (parallel version).
521 ///
522 /// This method allows plugins to register and load only the plugins that are not
523 /// dependencies of other plugins using parallel processing, and automatically unregisters unused plugins.
524 ///
525 /// # Parameters
526 ///
527 /// * `paths` - Parallel iterator of paths to plugin files or directories
528 ///
529 /// # Returns
530 ///
531 /// Returns `Result<Vec<Bundle>, PluginOperationError>`
532 /// containing the plugin bundles on success, or errors from registration, unregistration, or loading.
533 ///
534 /// # Type Parameters
535 ///
536 /// * `'b` - Lifetime of the path references
537 /// * `P` - Type of the parallel iterator containing path references
538 pub fn par_load_only_used_plugins<'b, P>(
539 &self,
540 paths: P,
541 ) -> Result<Vec<Bundle>, PluginOperationError>
542 where
543 P: IntoParallelIterator<Item = &'b str>,
544 {
545 self.loader.as_mut().par_load_only_used_plugins(paths)
546 }
547
548 /// Unloads a plugin from the execution environment.
549 ///
550 /// This method allows plugins to unload other plugins by ID and version.
551 ///
552 /// # Parameters
553 ///
554 /// * `id` - Plugin identifier
555 /// * `version` - Plugin version
556 ///
557 /// # Returns
558 ///
559 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
560 pub fn unload_plugin(&self, id: &str, version: &Version) -> Result<(), UnloadPluginError> {
561 self.loader.as_mut().unload_plugin(id, version)
562 }
563
564 /// Unloads a plugin from the execution environment (parallel version).
565 ///
566 /// This method allows plugins to unload other plugins by ID and version using parallel processing.
567 ///
568 /// # Parameters
569 ///
570 /// * `id` - Plugin identifier
571 /// * `version` - Plugin version
572 ///
573 /// # Returns
574 ///
575 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
576 pub fn par_unload_plugin(&self, id: &str, version: &Version) -> Result<(), UnloadPluginError> {
577 self.loader.as_mut().par_unload_plugin(id, version)
578 }
579
580 /// Unloads a plugin from the execution environment by bundle.
581 ///
582 /// This method allows plugins to unload other plugins by bundle information.
583 ///
584 /// # Parameters
585 ///
586 /// * `bundle` - Plugin bundle information
587 ///
588 /// # Returns
589 ///
590 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
591 pub fn unload_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), UnloadPluginError> {
592 self.loader.as_mut().unload_plugin_by_bundle(bundle)
593 }
594
595 /// Unloads a plugin from the execution environment by bundle (parallel version).
596 ///
597 /// This method allows plugins to unload other plugins by bundle information using parallel processing.
598 ///
599 /// # Parameters
600 ///
601 /// * `bundle` - Plugin bundle information
602 ///
603 /// # Returns
604 ///
605 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
606 pub fn par_unload_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), UnloadPluginError> {
607 self.loader.as_mut().par_unload_plugin_by_bundle(bundle)
608 }
609
610 /// Gets an immutable reference to a plugin by ID and version.
611 ///
612 /// This method allows plugins to access other registered plugins.
613 ///
614 /// # Parameters
615 ///
616 /// * `id` - Plugin identifier
617 /// * `version` - Plugin version
618 ///
619 /// # Returns
620 ///
621 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
622 pub fn get_plugin(&self, id: &str, version: &Version) -> Option<&Plugin<'static, O, I>> {
623 self.loader.as_ref().get_plugin(id, version)
624 }
625
626 /// Gets an immutable reference to a plugin by ID and version (parallel version).
627 ///
628 /// This method allows plugins to access other registered plugins using parallel processing.
629 ///
630 /// # Parameters
631 ///
632 /// * `id` - Plugin identifier
633 /// * `version` - Plugin version
634 ///
635 /// # Returns
636 ///
637 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
638 pub fn par_get_plugin(&self, id: &str, version: &Version) -> Option<&Plugin<'static, O, I>> {
639 self.loader.as_ref().par_get_plugin(id, version)
640 }
641
642 /// Gets an immutable reference to a plugin by bundle.
643 ///
644 /// This method allows plugins to access other registered plugins by bundle information.
645 ///
646 /// # Parameters
647 ///
648 /// * `bundle` - Plugin bundle information
649 ///
650 /// # Returns
651 ///
652 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
653 pub fn get_plugin_by_bundle(&self, bundle: &Bundle) -> Option<&Plugin<'static, O, I>> {
654 self.loader.as_ref().get_plugin_by_bundle(bundle)
655 }
656
657 /// Gets an immutable reference to a plugin by bundle (parallel version).
658 ///
659 /// This method allows plugins to access other registered plugins by bundle information using parallel processing.
660 ///
661 /// # Parameters
662 ///
663 /// * `bundle` - Plugin bundle information
664 ///
665 /// # Returns
666 ///
667 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
668 pub fn par_get_plugin_by_bundle(&self, bundle: &Bundle) -> Option<&Plugin<'static, O, I>> {
669 self.loader.as_ref().par_get_plugin_by_bundle(bundle)
670 }
671
672 /// Gets a mutable reference to a plugin by ID and version.
673 ///
674 /// This method allows plugins to access other registered plugins for modification.
675 ///
676 /// # Parameters
677 ///
678 /// * `id` - Plugin identifier
679 /// * `version` - Plugin version
680 ///
681 /// # Returns
682 ///
683 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
684 pub fn get_plugin_mut(
685 &self,
686 id: &str,
687 version: &Version,
688 ) -> Option<&mut Plugin<'static, O, I>> {
689 self.loader.as_mut().get_plugin_mut(id, version)
690 }
691
692 /// Gets a mutable reference to a plugin by ID and version (parallel version).
693 ///
694 /// This method allows plugins to access other registered plugins for modification using parallel processing.
695 ///
696 /// # Parameters
697 ///
698 /// * `id` - Plugin identifier
699 /// * `version` - Plugin version
700 ///
701 /// # Returns
702 ///
703 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
704 pub fn par_get_plugin_mut(
705 &self,
706 id: &str,
707 version: &Version,
708 ) -> Option<&mut Plugin<'static, O, I>> {
709 self.loader.as_mut().par_get_plugin_mut(id, version)
710 }
711
712 /// Gets a mutable reference to a plugin by bundle.
713 ///
714 /// This method allows plugins to access other registered plugins for modification by bundle information.
715 ///
716 /// # Parameters
717 ///
718 /// * `bundle` - Plugin bundle information
719 ///
720 /// # Returns
721 ///
722 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
723 pub fn get_plugin_mut_by_bundle(&self, bundle: &Bundle) -> Option<&mut Plugin<'static, O, I>> {
724 self.loader.as_mut().get_plugin_mut_by_bundle(bundle)
725 }
726
727 /// Gets a mutable reference to a plugin by bundle (parallel version).
728 ///
729 /// This method allows plugins to access other registered plugins for modification by bundle information using parallel processing.
730 ///
731 /// # Parameters
732 ///
733 /// * `bundle` - Plugin bundle information
734 ///
735 /// # Returns
736 ///
737 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
738 pub fn par_get_plugin_mut_by_bundle(
739 &self,
740 bundle: &Bundle,
741 ) -> Option<&mut Plugin<'static, O, I>> {
742 self.loader.as_mut().par_get_plugin_mut_by_bundle(bundle)
743 }
744
745 /// Gets all plugins with the specified ID.
746 ///
747 /// This method allows plugins to access all versions of plugins with a specific ID.
748 ///
749 /// # Parameters
750 ///
751 /// * `id` - Plugin identifier to search for
752 ///
753 /// # Returns
754 ///
755 /// Returns `Vec<&Plugin<'static, O, I>>` containing all matching plugins.
756 pub fn get_plugins_by_id(&self, id: &str) -> Vec<&Plugin<'static, O, I>> {
757 self.loader.as_ref().get_plugins_by_id(id)
758 }
759
760 /// Gets all plugins with the specified ID (parallel version).
761 ///
762 /// This method allows plugins to access all versions of plugins with a specific ID using parallel processing.
763 ///
764 /// # Parameters
765 ///
766 /// * `id` - Plugin identifier to search for
767 ///
768 /// # Returns
769 ///
770 /// Returns `Vec<&Plugin<'static, O, I>>` containing all matching plugins.
771 pub fn par_get_plugins_by_id(&self, id: &str) -> Vec<&Plugin<'static, O, I>> {
772 self.loader.as_ref().par_get_plugins_by_id(id)
773 }
774
775 /// Gets mutable references to all plugins with the specified ID.
776 ///
777 /// This method allows plugins to access all versions of plugins with a specific ID for modification.
778 ///
779 /// # Parameters
780 ///
781 /// * `id` - Plugin identifier to search for
782 ///
783 /// # Returns
784 ///
785 /// Returns `Vec<&mut Plugin<'static, O, I>>` containing all matching plugins.
786 pub fn get_plugins_by_id_mut(&self, id: &str) -> Vec<&mut Plugin<'static, O, I>> {
787 self.loader.as_mut().get_plugins_by_id_mut(id)
788 }
789
790 /// Gets mutable references to all plugins with the specified ID (parallel version).
791 ///
792 /// This method allows plugins to access all versions of plugins with a specific ID for modification using parallel processing.
793 ///
794 /// # Parameters
795 ///
796 /// * `id` - Plugin identifier to search for
797 ///
798 /// # Returns
799 ///
800 /// Returns `Vec<&mut Plugin<'static, O, I>>` containing all matching plugins.
801 pub fn par_get_plugins_by_id_mut(&self, id: &str) -> Vec<&mut Plugin<'static, O, I>> {
802 self.loader.as_mut().par_get_plugins_by_id_mut(id)
803 }
804
805 /// Gets a reference to all loaded plugins.
806 ///
807 /// This method allows plugins to access the complete list of loaded plugins.
808 ///
809 /// # Returns
810 ///
811 /// Returns `&Vec<Plugin<'static, O, I>>` containing all loaded plugins.
812 pub fn get_plugins(&self) -> &Vec<Plugin<'static, O, I>> {
813 self.loader.as_ref().get_plugins()
814 }
815
816 /// Gets a reference to the function registry.
817 ///
818 /// This method allows plugins to access the registry of functions available to plugins.
819 ///
820 /// # Returns
821 ///
822 /// Returns `&Registry<O>` containing the function registry.
823 pub fn get_registry(&self) -> &Registry<O> {
824 self.loader.as_ref().get_registry()
825 }
826
827 /// Gets a reference to the function requests.
828 ///
829 /// This method allows plugins to access the collection of function requests.
830 ///
831 /// # Returns
832 ///
833 /// Returns `&Requests` containing the function requests.
834 pub fn get_requests(&self) -> &Requests {
835 self.loader.as_ref().get_requests()
836 }
837
838 /// Calls a function request across all eligible plugins.
839 ///
840 /// This method allows plugins to call a function request on all plugins that have the highest
841 /// version for their ID (to avoid calling multiple versions of the same plugin).
842 ///
843 /// # Parameters
844 ///
845 /// * `name` - Name of the function request to call
846 /// * `args` - Arguments to pass to the function
847 ///
848 /// # Returns
849 ///
850 /// Returns `Result<Vec<O>, PluginCallRequestError>` containing results from all
851 /// eligible plugins that have the requested function.
852 pub fn call_request(
853 &self,
854 name: &str,
855 args: &[Variable],
856 ) -> Result<Vec<O>, PluginCallRequestError> {
857 self.loader.as_ref().call_request(name, args)
858 }
859
860 /// Calls a function request across all eligible plugins (parallel version).
861 ///
862 /// This method allows plugins to call a function request on all plugins that have the highest
863 /// version for their ID using parallel processing.
864 ///
865 /// # Parameters
866 ///
867 /// * `name` - Name of the function request to call
868 /// * `args` - Arguments to pass to the function
869 ///
870 /// # Returns
871 ///
872 /// Returns `Result<Vec<O>, PluginCallRequestError>` containing results from all
873 /// eligible plugins that have the requested function.
874 pub fn par_call_request(
875 &self,
876 name: &str,
877 args: &[Variable],
878 ) -> Result<Vec<O>, PluginCallRequestError> {
879 self.loader.as_ref().par_call_request(name, args)
880 }
881
882 /// Calls a function on a required dependency.
883 ///
884 /// This method allows the current plugin to call functions exposed by its required dependencies.
885 /// It ensures that the dependency exists and is loaded before attempting the call.
886 ///
887 /// # Parameters
888 ///
889 /// * `id` - Dependency plugin ID
890 /// * `version` - Dependency plugin version
891 /// * `name` - Function name to call
892 /// * `args` - Arguments to pass to the function
893 ///
894 /// # Returns
895 ///
896 /// Returns `Result<O, CallFunctionDependError>` containing the function result on success,
897 /// or an error if the dependency is not found or the function call fails.
898 ///
899 /// # Note
900 ///
901 /// This method only works with required dependencies. For optional dependencies,
902 /// use `call_function_optional_depend`.
903 pub fn call_function_depend(
904 &self,
905 id: &str,
906 version: &Version,
907 name: &str,
908 args: &[Variable],
909 ) -> Result<O, CallFunctionDependError> {
910 let depend = self
911 .depends
912 .iter()
913 .find(|&depend| *depend == (id, version))
914 .ok_or(CallFunctionDependError::DependNotFound)?;
915
916 let plugin = self
917 .loader
918 .as_ref()
919 .get_plugin_by_bundle(depend)
920 .ok_or(CallFunctionDependError::DependNotFound)?;
921
922 Ok(plugin.call_function(name, args)?)
923 }
924
925 /// Calls a function on an optional dependency.
926 ///
927 /// This method allows the current plugin to call functions exposed by its optional dependencies.
928 /// Unlike required dependencies, this method returns `None` if the dependency is not available.
929 ///
930 /// # Parameters
931 ///
932 /// * `id` - Optional dependency plugin ID
933 /// * `version` - Optional dependency plugin version
934 /// * `name` - Function name to call
935 /// * `args` - Arguments to pass to the function
936 ///
937 /// # Returns
938 ///
939 /// Returns `Result<Option<O>, PluginCallFunctionError>` containing:
940 /// - `Ok(Some(result))` if the dependency exists and the call succeeds
941 /// - `Ok(None)` if the dependency is not available
942 /// - `Err(error)` if the function call fails
943 ///
944 /// # Note
945 ///
946 /// This method only works with optional dependencies. For required dependencies,
947 /// use `call_function_depend`.
948 pub fn call_function_optional_depend(
949 &self,
950 id: &str,
951 version: &Version,
952 name: &str,
953 args: &[Variable],
954 ) -> Result<Option<O>, PluginCallFunctionError> {
955 let depend = self
956 .optional_depends
957 .iter()
958 .find(|&depend| *depend == (id, version));
959
960 depend
961 .and_then(|depend| self.loader.as_ref().get_plugin_by_bundle(depend))
962 .map(|plugin| plugin.call_function(name, args))
963 .transpose()
964 }
965}