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 Ptr, RegisterManagerError, RegisterPluginError, UnloadPluginError, UnregisterManagerError,
9 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, (Option<RegisterPluginError>, Option<LoadPluginError>)>`
439 /// containing the plugin bundle on success, or errors from registration or loading.
440 pub fn load_plugin_now(
441 &self,
442 path: &str,
443 ) -> Result<Bundle, (Option<RegisterPluginError>, Option<LoadPluginError>)> {
444 self.loader.as_mut().load_plugin_now(path)
445 }
446
447 /// Loads multiple plugins from the specified paths.
448 ///
449 /// This method allows plugins to register and load multiple plugins in sequence.
450 ///
451 /// # Parameters
452 ///
453 /// * `paths` - Iterator of paths to plugin files or directories
454 ///
455 /// # Returns
456 ///
457 /// Returns `Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<LoadPluginError>)>`
458 /// containing the plugin bundles on success, or errors from registration or loading.
459 ///
460 /// # Type Parameters
461 ///
462 /// * `'b` - Lifetime of the path references
463 /// * `P` - Type of the iterator containing path references
464 pub fn load_plugins<'b, P>(
465 &self,
466 paths: P,
467 ) -> Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<LoadPluginError>)>
468 where
469 P: IntoIterator<Item = &'b str>,
470 {
471 self.loader.as_mut().load_plugins(paths)
472 }
473
474 /// Loads multiple plugins from the specified paths (parallel version).
475 ///
476 /// This method allows plugins to register and load multiple plugins concurrently.
477 ///
478 /// # Parameters
479 ///
480 /// * `paths` - Parallel iterator of paths to plugin files or directories
481 ///
482 /// # Returns
483 ///
484 /// Returns `Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<LoadPluginError>)>`
485 /// containing the plugin bundles on success, or errors from registration or loading.
486 ///
487 /// # Type Parameters
488 ///
489 /// * `'b` - Lifetime of the path references
490 /// * `P` - Type of the parallel iterator containing path references
491 pub fn par_load_plugins<'b, P>(
492 &self,
493 paths: P,
494 ) -> Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<LoadPluginError>)>
495 where
496 P: IntoParallelIterator<Item = &'b str>,
497 {
498 self.loader.as_mut().par_load_plugins(paths)
499 }
500
501 /// Loads only the plugins that are used (not dependencies of other plugins).
502 ///
503 /// This method allows plugins to register and load only the plugins that are not
504 /// dependencies of other plugins, and automatically unregisters unused plugins.
505 ///
506 /// # Parameters
507 ///
508 /// * `paths` - Iterator of paths to plugin files or directories
509 ///
510 /// # Returns
511 ///
512 /// Returns `Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<UnregisterPluginError>, Option<LoadPluginError>)>`
513 /// containing the plugin bundles on success, or errors from registration, unregistration, or loading.
514 ///
515 /// # Type Parameters
516 ///
517 /// * `'b` - Lifetime of the path references
518 /// * `P` - Type of the iterator containing path references
519 pub fn load_only_used_plugins<'b, P>(
520 &self,
521 paths: P,
522 ) -> Result<
523 Vec<Bundle>,
524 (
525 Option<RegisterPluginError>,
526 Option<UnregisterPluginError>,
527 Option<LoadPluginError>,
528 ),
529 >
530 where
531 P: IntoIterator<Item = &'b str>,
532 {
533 self.loader.as_mut().load_only_used_plugins(paths)
534 }
535
536 /// Loads only the plugins that are used (not dependencies of other plugins) (parallel version).
537 ///
538 /// This method allows plugins to register and load only the plugins that are not
539 /// dependencies of other plugins using parallel processing, and automatically unregisters unused plugins.
540 ///
541 /// # Parameters
542 ///
543 /// * `paths` - Parallel iterator of paths to plugin files or directories
544 ///
545 /// # Returns
546 ///
547 /// Returns `Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<UnregisterPluginError>, Option<LoadPluginError>)>`
548 /// containing the plugin bundles on success, or errors from registration, unregistration, or loading.
549 ///
550 /// # Type Parameters
551 ///
552 /// * `'b` - Lifetime of the path references
553 /// * `P` - Type of the parallel iterator containing path references
554 pub fn par_load_only_used_plugins<'b, P>(
555 &self,
556 paths: P,
557 ) -> Result<
558 Vec<Bundle>,
559 (
560 Option<RegisterPluginError>,
561 Option<UnregisterPluginError>,
562 Option<LoadPluginError>,
563 ),
564 >
565 where
566 P: IntoParallelIterator<Item = &'b str>,
567 {
568 self.loader.as_mut().par_load_only_used_plugins(paths)
569 }
570
571 /// Unloads a plugin from the execution environment.
572 ///
573 /// This method allows plugins to unload other plugins by ID and version.
574 ///
575 /// # Parameters
576 ///
577 /// * `id` - Plugin identifier
578 /// * `version` - Plugin version
579 ///
580 /// # Returns
581 ///
582 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
583 pub fn unload_plugin(&self, id: &str, version: &Version) -> Result<(), UnloadPluginError> {
584 self.loader.as_mut().unload_plugin(id, version)
585 }
586
587 /// Unloads a plugin from the execution environment (parallel version).
588 ///
589 /// This method allows plugins to unload other plugins by ID and version using parallel processing.
590 ///
591 /// # Parameters
592 ///
593 /// * `id` - Plugin identifier
594 /// * `version` - Plugin version
595 ///
596 /// # Returns
597 ///
598 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
599 pub fn par_unload_plugin(&self, id: &str, version: &Version) -> Result<(), UnloadPluginError> {
600 self.loader.as_mut().par_unload_plugin(id, version)
601 }
602
603 /// Unloads a plugin from the execution environment by bundle.
604 ///
605 /// This method allows plugins to unload other plugins by bundle information.
606 ///
607 /// # Parameters
608 ///
609 /// * `bundle` - Plugin bundle information
610 ///
611 /// # Returns
612 ///
613 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
614 pub fn unload_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), UnloadPluginError> {
615 self.loader.as_mut().unload_plugin_by_bundle(bundle)
616 }
617
618 /// Unloads a plugin from the execution environment by bundle (parallel version).
619 ///
620 /// This method allows plugins to unload other plugins by bundle information using parallel processing.
621 ///
622 /// # Parameters
623 ///
624 /// * `bundle` - Plugin bundle information
625 ///
626 /// # Returns
627 ///
628 /// Returns `Result<(), UnloadPluginError>` indicating success or failure.
629 pub fn par_unload_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), UnloadPluginError> {
630 self.loader.as_mut().par_unload_plugin_by_bundle(bundle)
631 }
632
633 /// Gets an immutable reference to a plugin by ID and version.
634 ///
635 /// This method allows plugins to access other registered plugins.
636 ///
637 /// # Parameters
638 ///
639 /// * `id` - Plugin identifier
640 /// * `version` - Plugin version
641 ///
642 /// # Returns
643 ///
644 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
645 pub fn get_plugin(&self, id: &str, version: &Version) -> Option<&Plugin<'static, O, I>> {
646 self.loader.as_ref().get_plugin(id, version)
647 }
648
649 /// Gets an immutable reference to a plugin by ID and version (parallel version).
650 ///
651 /// This method allows plugins to access other registered plugins using parallel processing.
652 ///
653 /// # Parameters
654 ///
655 /// * `id` - Plugin identifier
656 /// * `version` - Plugin version
657 ///
658 /// # Returns
659 ///
660 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
661 pub fn par_get_plugin(&self, id: &str, version: &Version) -> Option<&Plugin<'static, O, I>> {
662 self.loader.as_ref().par_get_plugin(id, version)
663 }
664
665 /// Gets an immutable reference to a plugin by bundle.
666 ///
667 /// This method allows plugins to access other registered plugins by bundle information.
668 ///
669 /// # Parameters
670 ///
671 /// * `bundle` - Plugin bundle information
672 ///
673 /// # Returns
674 ///
675 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
676 pub fn get_plugin_by_bundle(&self, bundle: &Bundle) -> Option<&Plugin<'static, O, I>> {
677 self.loader.as_ref().get_plugin_by_bundle(bundle)
678 }
679
680 /// Gets an immutable reference to a plugin by bundle (parallel version).
681 ///
682 /// This method allows plugins to access other registered plugins by bundle information using parallel processing.
683 ///
684 /// # Parameters
685 ///
686 /// * `bundle` - Plugin bundle information
687 ///
688 /// # Returns
689 ///
690 /// Returns `Option<&Plugin<'static, O, I>>` containing the plugin if found.
691 pub fn par_get_plugin_by_bundle(&self, bundle: &Bundle) -> Option<&Plugin<'static, O, I>> {
692 self.loader.as_ref().par_get_plugin_by_bundle(bundle)
693 }
694
695 /// Gets a mutable reference to a plugin by ID and version.
696 ///
697 /// This method allows plugins to access other registered plugins for modification.
698 ///
699 /// # Parameters
700 ///
701 /// * `id` - Plugin identifier
702 /// * `version` - Plugin version
703 ///
704 /// # Returns
705 ///
706 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
707 pub fn get_plugin_mut(
708 &self,
709 id: &str,
710 version: &Version,
711 ) -> Option<&mut Plugin<'static, O, I>> {
712 self.loader.as_mut().get_plugin_mut(id, version)
713 }
714
715 /// Gets a mutable reference to a plugin by ID and version (parallel version).
716 ///
717 /// This method allows plugins to access other registered plugins for modification using parallel processing.
718 ///
719 /// # Parameters
720 ///
721 /// * `id` - Plugin identifier
722 /// * `version` - Plugin version
723 ///
724 /// # Returns
725 ///
726 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
727 pub fn par_get_plugin_mut(
728 &self,
729 id: &str,
730 version: &Version,
731 ) -> Option<&mut Plugin<'static, O, I>> {
732 self.loader.as_mut().par_get_plugin_mut(id, version)
733 }
734
735 /// Gets a mutable reference to a plugin by bundle.
736 ///
737 /// This method allows plugins to access other registered plugins for modification by bundle information.
738 ///
739 /// # Parameters
740 ///
741 /// * `bundle` - Plugin bundle information
742 ///
743 /// # Returns
744 ///
745 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
746 pub fn get_plugin_mut_by_bundle(&self, bundle: &Bundle) -> Option<&mut Plugin<'static, O, I>> {
747 self.loader.as_mut().get_plugin_mut_by_bundle(bundle)
748 }
749
750 /// Gets a mutable reference to a plugin by bundle (parallel version).
751 ///
752 /// This method allows plugins to access other registered plugins for modification by bundle information using parallel processing.
753 ///
754 /// # Parameters
755 ///
756 /// * `bundle` - Plugin bundle information
757 ///
758 /// # Returns
759 ///
760 /// Returns `Option<&mut Plugin<'static, O, I>>` containing the plugin if found.
761 pub fn par_get_plugin_mut_by_bundle(
762 &self,
763 bundle: &Bundle,
764 ) -> Option<&mut Plugin<'static, O, I>> {
765 self.loader.as_mut().par_get_plugin_mut_by_bundle(bundle)
766 }
767
768 /// Gets all plugins with the specified ID.
769 ///
770 /// This method allows plugins to access all versions of plugins with a specific ID.
771 ///
772 /// # Parameters
773 ///
774 /// * `id` - Plugin identifier to search for
775 ///
776 /// # Returns
777 ///
778 /// Returns `Vec<&Plugin<'static, O, I>>` containing all matching plugins.
779 pub fn get_plugins_by_id(&self, id: &str) -> Vec<&Plugin<'static, O, I>> {
780 self.loader.as_ref().get_plugins_by_id(id)
781 }
782
783 /// Gets all plugins with the specified ID (parallel version).
784 ///
785 /// This method allows plugins to access all versions of plugins with a specific ID using parallel processing.
786 ///
787 /// # Parameters
788 ///
789 /// * `id` - Plugin identifier to search for
790 ///
791 /// # Returns
792 ///
793 /// Returns `Vec<&Plugin<'static, O, I>>` containing all matching plugins.
794 pub fn par_get_plugins_by_id(&self, id: &str) -> Vec<&Plugin<'static, O, I>> {
795 self.loader.as_ref().par_get_plugins_by_id(id)
796 }
797
798 /// Gets mutable references to all plugins with the specified ID.
799 ///
800 /// This method allows plugins to access all versions of plugins with a specific ID for modification.
801 ///
802 /// # Parameters
803 ///
804 /// * `id` - Plugin identifier to search for
805 ///
806 /// # Returns
807 ///
808 /// Returns `Vec<&mut Plugin<'static, O, I>>` containing all matching plugins.
809 pub fn get_plugins_by_id_mut(&self, id: &str) -> Vec<&mut Plugin<'static, O, I>> {
810 self.loader.as_mut().get_plugins_by_id_mut(id)
811 }
812
813 /// Gets mutable references to all plugins with the specified ID (parallel version).
814 ///
815 /// This method allows plugins to access all versions of plugins with a specific ID for modification using parallel processing.
816 ///
817 /// # Parameters
818 ///
819 /// * `id` - Plugin identifier to search for
820 ///
821 /// # Returns
822 ///
823 /// Returns `Vec<&mut Plugin<'static, O, I>>` containing all matching plugins.
824 pub fn par_get_plugins_by_id_mut(&self, id: &str) -> Vec<&mut Plugin<'static, O, I>> {
825 self.loader.as_mut().par_get_plugins_by_id_mut(id)
826 }
827
828 /// Gets a reference to all loaded plugins.
829 ///
830 /// This method allows plugins to access the complete list of loaded plugins.
831 ///
832 /// # Returns
833 ///
834 /// Returns `&Vec<Plugin<'static, O, I>>` containing all loaded plugins.
835 pub fn get_plugins(&self) -> &Vec<Plugin<'static, O, I>> {
836 self.loader.as_ref().get_plugins()
837 }
838
839 /// Gets a reference to the function registry.
840 ///
841 /// This method allows plugins to access the registry of functions available to plugins.
842 ///
843 /// # Returns
844 ///
845 /// Returns `&Registry<O>` containing the function registry.
846 pub fn get_registry(&self) -> &Registry<O> {
847 self.loader.as_ref().get_registry()
848 }
849
850 /// Gets a reference to the function requests.
851 ///
852 /// This method allows plugins to access the collection of function requests.
853 ///
854 /// # Returns
855 ///
856 /// Returns `&Requests` containing the function requests.
857 pub fn get_requests(&self) -> &Requests {
858 self.loader.as_ref().get_requests()
859 }
860
861 /// Calls a function request across all eligible plugins.
862 ///
863 /// This method allows plugins to call a function request on all plugins that have the highest
864 /// version for their ID (to avoid calling multiple versions of the same plugin).
865 ///
866 /// # Parameters
867 ///
868 /// * `name` - Name of the function request to call
869 /// * `args` - Arguments to pass to the function
870 ///
871 /// # Returns
872 ///
873 /// Returns `Result<Vec<O>, PluginCallRequestError>` containing results from all
874 /// eligible plugins that have the requested function.
875 pub fn call_request(
876 &self,
877 name: &str,
878 args: &[Variable],
879 ) -> Result<Vec<O>, PluginCallRequestError> {
880 self.loader.as_ref().call_request(name, args)
881 }
882
883 /// Calls a function request across all eligible plugins (parallel version).
884 ///
885 /// This method allows plugins to call a function request on all plugins that have the highest
886 /// version for their ID using parallel processing.
887 ///
888 /// # Parameters
889 ///
890 /// * `name` - Name of the function request to call
891 /// * `args` - Arguments to pass to the function
892 ///
893 /// # Returns
894 ///
895 /// Returns `Result<Vec<O>, PluginCallRequestError>` containing results from all
896 /// eligible plugins that have the requested function.
897 pub fn par_call_request(
898 &self,
899 name: &str,
900 args: &[Variable],
901 ) -> Result<Vec<O>, PluginCallRequestError> {
902 self.loader.as_ref().par_call_request(name, args)
903 }
904
905 /// Calls a function on a required dependency.
906 ///
907 /// This method allows the current plugin to call functions exposed by its required dependencies.
908 /// It ensures that the dependency exists and is loaded before attempting the call.
909 ///
910 /// # Parameters
911 ///
912 /// * `id` - Dependency plugin ID
913 /// * `version` - Dependency plugin version
914 /// * `name` - Function name to call
915 /// * `args` - Arguments to pass to the function
916 ///
917 /// # Returns
918 ///
919 /// Returns `Result<O, CallFunctionDependError>` containing the function result on success,
920 /// or an error if the dependency is not found or the function call fails.
921 ///
922 /// # Note
923 ///
924 /// This method only works with required dependencies. For optional dependencies,
925 /// use `call_function_optional_depend`.
926 pub fn call_function_depend(
927 &self,
928 id: &str,
929 version: &Version,
930 name: &str,
931 args: &[Variable],
932 ) -> Result<O, CallFunctionDependError> {
933 let depend = self
934 .depends
935 .iter()
936 .find(|&depend| *depend == (id, version))
937 .ok_or(CallFunctionDependError::DependNotFound)?;
938
939 let plugin = self
940 .loader
941 .as_ref()
942 .get_plugin_by_bundle(depend)
943 .ok_or(CallFunctionDependError::DependNotFound)?;
944
945 Ok(plugin.call_function(name, args)?)
946 }
947
948 /// Calls a function on an optional dependency.
949 ///
950 /// This method allows the current plugin to call functions exposed by its optional dependencies.
951 /// Unlike required dependencies, this method returns `None` if the dependency is not available.
952 ///
953 /// # Parameters
954 ///
955 /// * `id` - Optional dependency plugin ID
956 /// * `version` - Optional dependency plugin version
957 /// * `name` - Function name to call
958 /// * `args` - Arguments to pass to the function
959 ///
960 /// # Returns
961 ///
962 /// Returns `Result<Option<O>, PluginCallFunctionError>` containing:
963 /// - `Ok(Some(result))` if the dependency exists and the call succeeds
964 /// - `Ok(None)` if the dependency is not available
965 /// - `Err(error)` if the function call fails
966 ///
967 /// # Note
968 ///
969 /// This method only works with optional dependencies. For required dependencies,
970 /// use `call_function_depend`.
971 pub fn call_function_optional_depend(
972 &self,
973 id: &str,
974 version: &Version,
975 name: &str,
976 args: &[Variable],
977 ) -> Result<Option<O>, PluginCallFunctionError> {
978 let depend = self
979 .optional_depends
980 .iter()
981 .find(|&depend| *depend == (id, version));
982
983 depend
984 .and_then(|depend| self.loader.as_ref().get_plugin_by_bundle(depend))
985 .map(|plugin| plugin.call_function(name, args))
986 .transpose()
987 }
988}