1use rayon::prelude::IntoParallelIterator;
2use semver::Version;
3
4use crate::{
5 utils::{
6 CallFunctionDependError, LoadPluginError, PluginCallFunctionError, PluginCallRequestError,
7 Ptr, RegisterManagerError, RegisterPluginError, UnloadPluginError, UnregisterManagerError,
8 UnregisterPluginError,
9 },
10 variable::Variable,
11 Bundle, Info, Loader, Manager, Plugin, Registry, Requests,
12};
13
14pub struct Api<O: Send + Sync + 'static, I: Info + 'static> {
15 loader: Ptr<'static, Loader<'static, O, I>>,
16 plugin: Bundle,
17 depends: Vec<Bundle>,
18 optional_depends: Vec<Bundle>,
19}
20
21impl<O: Send + Sync + 'static, I: Info + 'static> Api<O, I> {
22 pub(crate) const fn new(
23 loader: Ptr<'static, Loader<'static, O, I>>,
24 plugin: Bundle,
25 depends: Vec<Bundle>,
26 optional_depends: Vec<Bundle>,
27 ) -> Self {
28 Self {
29 loader,
30 plugin,
31 depends,
32 optional_depends,
33 }
34 }
35
36 pub fn registry(&self) -> &Registry<O> {
37 &self.loader.as_ref().registry
38 }
39
40 pub const fn plugin(&self) -> &Bundle {
41 &self.plugin
42 }
43
44 pub const fn depends(&self) -> &Vec<Bundle> {
45 &self.depends
46 }
47
48 pub const fn optional_depends(&self) -> &Vec<Bundle> {
49 &self.optional_depends
50 }
51
52 pub fn register_manager<M>(&self, manager: M) -> Result<(), RegisterManagerError>
55 where
56 M: Manager<'static, O, I> + 'static,
57 {
58 self.loader.as_mut().register_manager(manager)
59 }
60
61 pub fn register_managers<M>(&self, managers: M) -> Result<(), RegisterManagerError>
62 where
63 M: IntoIterator<Item = Box<dyn Manager<'static, O, I>>>,
64 {
65 self.loader.as_mut().register_managers(managers)
66 }
67
68 pub fn par_register_managers<M>(&self, managers: M) -> Result<(), RegisterManagerError>
69 where
70 M: IntoParallelIterator<Item = Box<dyn Manager<'static, O, I>>>,
71 {
72 self.loader.as_mut().par_register_managers(managers)
73 }
74
75 pub fn unregister_manager(&self, format: &str) -> Result<(), UnregisterManagerError> {
76 self.loader.as_mut().unregister_manager(format)
77 }
78
79 pub fn get_manager_ref(&self, format: &str) -> Option<&Box<dyn Manager<'static, O, I>>> {
80 self.loader.as_ref().get_manager_ref(format)
81 }
82
83 pub fn par_get_manager_ref(&self, format: &str) -> Option<&Box<dyn Manager<'static, O, I>>> {
84 self.loader.as_ref().par_get_manager_ref(format)
85 }
86
87 pub fn get_manager_mut(&self, format: &str) -> Option<&mut Box<dyn Manager<'static, O, I>>> {
88 self.loader.as_mut().get_manager_mut(format)
89 }
90
91 pub fn par_get_manager_mut(
92 &self,
93 format: &str,
94 ) -> Option<&mut Box<dyn Manager<'static, O, I>>> {
95 self.loader.as_mut().par_get_manager_mut(format)
96 }
97
98 pub fn register_plugin(&self, path: &str) -> Result<Bundle, RegisterPluginError> {
99 self.loader.as_mut().register_plugin(path)
100 }
101
102 pub fn register_plugins<'b, P>(&self, paths: P) -> Result<Vec<Bundle>, RegisterPluginError>
103 where
104 P: IntoIterator<Item = &'b str>,
105 {
106 self.loader.as_mut().register_plugins(paths)
107 }
108
109 pub fn par_register_plugins<'b, P>(&self, paths: P) -> Result<Vec<Bundle>, RegisterPluginError>
110 where
111 P: IntoParallelIterator<Item = &'b str>,
112 {
113 self.loader.as_mut().par_register_plugins(paths)
114 }
115
116 pub fn unregister_plugin(
117 &self,
118 id: &str,
119 version: &Version,
120 ) -> Result<(), UnregisterPluginError> {
121 self.loader.as_mut().unregister_plugin(id, version)
122 }
123
124 pub fn unregister_plugin_by_bundle(
125 &self,
126 bundle: &Bundle,
127 ) -> Result<(), UnregisterPluginError> {
128 self.loader.as_mut().unregister_plugin_by_bundle(bundle)
129 }
130
131 pub fn par_unregister_plugin_by_bundle(
132 &self,
133 bundle: &Bundle,
134 ) -> Result<(), UnregisterPluginError> {
135 self.loader.as_mut().par_unregister_plugin_by_bundle(bundle)
136 }
137
138 pub fn load_plugin(&self, id: &str, version: &Version) -> Result<(), LoadPluginError> {
139 self.loader.as_mut().load_plugin(id, version)
140 }
141
142 pub fn par_load_plugin(&self, id: &str, version: &Version) -> Result<(), LoadPluginError> {
143 self.loader.as_mut().par_load_plugin(id, version)
144 }
145
146 pub fn load_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), LoadPluginError> {
147 self.loader.as_mut().load_plugin_by_bundle(bundle)
148 }
149
150 pub fn par_load_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), LoadPluginError> {
151 self.loader.as_mut().par_load_plugin_by_bundle(bundle)
152 }
153
154 pub fn load_plugin_now(
155 &self,
156 path: &str,
157 ) -> Result<Bundle, (Option<RegisterPluginError>, Option<LoadPluginError>)> {
158 self.loader.as_mut().load_plugin_now(path)
159 }
160
161 pub fn load_plugins<'b, P>(
162 &self,
163 paths: P,
164 ) -> Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<LoadPluginError>)>
165 where
166 P: IntoIterator<Item = &'b str>,
167 {
168 self.loader.as_mut().load_plugins(paths)
169 }
170
171 pub fn par_load_plugins<'b, P>(
172 &self,
173 paths: P,
174 ) -> Result<Vec<Bundle>, (Option<RegisterPluginError>, Option<LoadPluginError>)>
175 where
176 P: IntoParallelIterator<Item = &'b str>,
177 {
178 self.loader.as_mut().par_load_plugins(paths)
179 }
180
181 pub fn load_only_used_plugins<'b, P>(
182 &self,
183 paths: P,
184 ) -> Result<
185 Vec<Bundle>,
186 (
187 Option<RegisterPluginError>,
188 Option<UnregisterPluginError>,
189 Option<LoadPluginError>,
190 ),
191 >
192 where
193 P: IntoIterator<Item = &'b str>,
194 {
195 self.loader.as_mut().load_only_used_plugins(paths)
196 }
197
198 pub fn par_load_only_used_plugins<'b, P>(
199 &self,
200 paths: P,
201 ) -> Result<
202 Vec<Bundle>,
203 (
204 Option<RegisterPluginError>,
205 Option<UnregisterPluginError>,
206 Option<LoadPluginError>,
207 ),
208 >
209 where
210 P: IntoParallelIterator<Item = &'b str>,
211 {
212 self.loader.as_mut().par_load_only_used_plugins(paths)
213 }
214
215 pub fn unload_plugin(&self, id: &str, version: &Version) -> Result<(), UnloadPluginError> {
216 self.loader.as_mut().unload_plugin(id, version)
217 }
218
219 pub fn par_unload_plugin(&self, id: &str, version: &Version) -> Result<(), UnloadPluginError> {
220 self.loader.as_mut().par_unload_plugin(id, version)
221 }
222
223 pub fn unload_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), UnloadPluginError> {
224 self.loader.as_mut().unload_plugin_by_bundle(bundle)
225 }
226
227 pub fn par_unload_plugin_by_bundle(&self, bundle: &Bundle) -> Result<(), UnloadPluginError> {
228 self.loader.as_mut().par_unload_plugin_by_bundle(bundle)
229 }
230
231 pub fn get_plugin(&self, id: &str, version: &Version) -> Option<&Plugin<'static, O, I>> {
232 self.loader.as_ref().get_plugin(id, version)
233 }
234
235 pub fn par_get_plugin(&self, id: &str, version: &Version) -> Option<&Plugin<'static, O, I>> {
236 self.loader.as_ref().par_get_plugin(id, version)
237 }
238
239 pub fn get_plugin_by_bundle(&self, bundle: &Bundle) -> Option<&Plugin<'static, O, I>> {
240 self.loader.as_ref().get_plugin_by_bundle(bundle)
241 }
242
243 pub fn par_get_plugin_by_bundle(&self, bundle: &Bundle) -> Option<&Plugin<'static, O, I>> {
244 self.loader.as_ref().par_get_plugin_by_bundle(bundle)
245 }
246
247 pub fn get_plugin_mut(
248 &self,
249 id: &str,
250 version: &Version,
251 ) -> Option<&mut Plugin<'static, O, I>> {
252 self.loader.as_mut().get_plugin_mut(id, version)
253 }
254
255 pub fn par_get_plugin_mut(
256 &self,
257 id: &str,
258 version: &Version,
259 ) -> Option<&mut Plugin<'static, O, I>> {
260 self.loader.as_mut().par_get_plugin_mut(id, version)
261 }
262
263 pub fn get_plugin_mut_by_bundle(&self, bundle: &Bundle) -> Option<&mut Plugin<'static, O, I>> {
264 self.loader.as_mut().get_plugin_mut_by_bundle(bundle)
265 }
266
267 pub fn par_get_plugin_mut_by_bundle(
268 &self,
269 bundle: &Bundle,
270 ) -> Option<&mut Plugin<'static, O, I>> {
271 self.loader.as_mut().par_get_plugin_mut_by_bundle(bundle)
272 }
273
274 pub fn get_plugins_by_id(&self, id: &str) -> Vec<&Plugin<'static, O, I>> {
275 self.loader.as_ref().get_plugins_by_id(id)
276 }
277
278 pub fn par_get_plugins_by_id(&self, id: &str) -> Vec<&Plugin<'static, O, I>> {
279 self.loader.as_ref().par_get_plugins_by_id(id)
280 }
281
282 pub fn get_plugins_by_id_mut(&self, id: &str) -> Vec<&mut Plugin<'static, O, I>> {
283 self.loader.as_mut().get_plugins_by_id_mut(id)
284 }
285
286 pub fn par_get_plugins_by_id_mut(&self, id: &str) -> Vec<&mut Plugin<'static, O, I>> {
287 self.loader.as_mut().par_get_plugins_by_id_mut(id)
288 }
289
290 pub fn get_plugins(&self) -> &Vec<Plugin<'static, O, I>> {
291 self.loader.as_ref().get_plugins()
292 }
293
294 pub fn get_registry(&self) -> &Registry<O> {
295 self.loader.as_ref().get_registry()
296 }
297
298 pub fn get_requests(&self) -> &Requests {
299 self.loader.as_ref().get_requests()
300 }
301
302 pub fn call_request(
303 &self,
304 name: &str,
305 args: &[Variable],
306 ) -> Result<Vec<O>, PluginCallRequestError> {
307 self.loader.as_ref().call_request(name, args)
308 }
309
310 pub fn par_call_request(
311 &self,
312 name: &str,
313 args: &[Variable],
314 ) -> Result<Vec<O>, PluginCallRequestError> {
315 self.loader.as_ref().par_call_request(name, args)
316 }
317
318 pub fn call_function_depend(
322 &self,
323 id: &str,
324 version: &Version,
325 name: &str,
326 args: &[Variable],
327 ) -> Result<O, CallFunctionDependError> {
328 let depend = self
329 .depends
330 .iter()
331 .find(|&depend| *depend == (id, version))
332 .ok_or(CallFunctionDependError::DependNotFound)?;
333
334 let plugin = self
335 .loader
336 .as_ref()
337 .get_plugin_by_bundle(depend)
338 .ok_or(CallFunctionDependError::DependNotFound)?;
339
340 Ok(plugin.call_function(name, args)?)
341 }
342
343 pub fn call_function_optional_depend(
345 &self,
346 id: &str,
347 version: &Version,
348 name: &str,
349 args: &[Variable],
350 ) -> Result<Option<O>, PluginCallFunctionError> {
351 let depend = self
352 .optional_depends
353 .iter()
354 .find(|&depend| *depend == (id, version));
355
356 depend
357 .and_then(|depend| self.loader.as_ref().get_plugin_by_bundle(depend))
358 .map(|plugin| plugin.call_function(name, args))
359 .transpose()
360 }
361}