Skip to main content

slowshell_plugin_abi/
root.rs

1use abi_stable::{
2  StableAbi,
3  library::RootModule,
4  std_types::{RSlice, RStr},
5};
6
7use crate::host::HostRef;
8
9#[repr(C)]
10#[derive(StableAbi, Clone, Copy, Debug)]
11pub struct PluginDependency {
12  pub id: RStr<'static>,
13  pub version_req: RStr<'static>,
14}
15
16fn no_requirements() -> RSlice<'static, PluginDependency> {
17  RSlice::EMPTY
18}
19
20#[repr(C)]
21#[derive(StableAbi)]
22#[sabi(kind(Prefix(prefix_ref = PluginMod_Ref, prefix_fields = PluginMod_Prefix)))]
23#[sabi(missing_field(panic))]
24pub struct PluginMod {
25  pub id: RStr<'static>,
26  pub version: RStr<'static>,
27
28  #[sabi(last_prefix_field)]
29  pub register: extern "C" fn(HostRef<'_>),
30
31  #[sabi(missing_field(with = no_requirements))]
32  pub requires: RSlice<'static, PluginDependency>,
33}
34
35impl RootModule for PluginMod_Ref {
36  abi_stable::declare_root_module_statics! { PluginMod_Ref }
37  const BASE_NAME: &'static str = "slowshell_plugin";
38  const NAME: &'static str = "slowshell_plugin";
39  const VERSION_STRINGS: abi_stable::sabi_types::VersionStrings =
40    abi_stable::package_version_strings!();
41}
42
43/// Exports the plugin stuff.
44///
45///
46/// ```ignore
47/// use slowshell_plugin_abi::prelude::*;
48///
49/// struct Hello;
50/// impl Component for Hello {
51///   fn new(_ctx: &Context<'_>) -> Self { Hello }
52///   fn view(&self, _ctx: &Context<'_>) -> Node { Node::text("hello") }
53/// }
54///
55/// fn register(host: HostRef<'_>) {
56///   host.component::<Hello>("example/hello");
57/// }
58///
59/// export_plugin!(register);
60/// ```
61///
62/// ```ignore
63/// export_plugin!(register, requires = [("other-plugin", "^0.2")]);
64/// ```
65#[macro_export]
66macro_rules! export_plugin {
67  ($register:path) => {
68    $crate::export_plugin!($register, requires = []);
69  };
70  ($register:path, requires = [$(($id:literal, $req:literal)),* $(,)?]) => {
71    #[doc(hidden)]
72    extern "C" fn __slowshell_plugin_register(host: $crate::HostRef<'_>) {
73      $register(host);
74    }
75
76    #[doc(hidden)]
77    const __SLOWSHELL_REQUIRES: &[$crate::PluginDependency] = &[
78      $($crate::PluginDependency {
79        id: $crate::RStr::from_str($id),
80        version_req: $crate::RStr::from_str($req),
81      }),*
82    ];
83
84    #[doc(hidden)]
85    #[$crate::export_root_module]
86    pub fn __slowshell_plugin_root_module() -> $crate::PluginMod_Ref {
87      $crate::PrefixTypeTrait::leak_into_prefix($crate::PluginMod {
88        id: $crate::RStr::from_str(env!("CARGO_PKG_NAME")),
89        version: $crate::RStr::from_str(env!("CARGO_PKG_VERSION")),
90        register: __slowshell_plugin_register,
91        requires: $crate::RSlice::from_slice(__SLOWSHELL_REQUIRES),
92      })
93    }
94  };
95}