1use crate::frontend::BoxDynFrontend;
2use crate::provider::BoxDynProvider;
3use crate::{BoxDynFrontendContext, config::PluginConfigAdapter};
4use abi_stable::{StableAbi, std_types::RString};
5
6pub type ProviderFactory = extern "C" fn(&PluginConfigAdapter<'_>) -> BoxDynProvider;
7pub type FrontendFactory = extern "C" fn(BoxDynFrontendContext, &PluginConfigAdapter<'_>) -> BoxDynFrontend;
8
9#[repr(u8)]
11#[derive(StableAbi, Debug)]
12pub enum PluginFactory {
13 Provider(extern "C" fn(&PluginConfigAdapter<'_>) -> BoxDynProvider),
15 Frontend(extern "C" fn(BoxDynFrontendContext, &PluginConfigAdapter<'_>) -> BoxDynFrontend),
16}
17
18impl PluginFactory {
19 pub fn provider(&self) -> Option<ProviderFactory> {
21 if let Self::Provider(factory) = self {
22 return Some(*factory);
23 }
24
25 None
26 }
27
28 pub fn frontend(&self) -> Option<FrontendFactory> {
30 if let Self::Frontend(factory) = self {
31 return Some(*factory);
32 }
33
34 None
35 }
36}
37
38#[repr(C)]
40#[derive(StableAbi, Debug)]
41pub struct PluginDefinition {
42 pub meta: PluginMetadata,
43 pub factory: PluginFactory,
44}
45
46#[repr(C)]
48#[derive(StableAbi, Debug)]
49pub struct PluginMetadata {
50 pub name: RString,
51}
52
53impl PluginMetadata {
54 #[must_use]
55 pub fn new(name: impl Into<RString>) -> Self {
56 Self { name: name.into() }
57 }
58
59 #[must_use]
60 pub fn with_provider(self, factory: ProviderFactory) -> PluginDefinition {
61 PluginDefinition {
62 meta: self,
63 factory: PluginFactory::Provider(factory),
64 }
65 }
66
67 #[must_use]
68 pub fn with_frontend(self, factory: FrontendFactory) -> PluginDefinition {
69 PluginDefinition {
70 meta: self,
71 factory: PluginFactory::Frontend(factory),
72 }
73 }
74}