openrr_plugin/
lib.rs
1#![doc = include_str!("../README.md")]
2#![warn(missing_docs)]
3#![allow(non_local_definitions)] mod proxy;
6
7#[rustfmt::skip]
8#[path = "gen/api.rs"]
9mod api;
10
11use std::{
12 fmt,
13 path::Path,
14 sync::{Arc, LazyLock},
15};
16
17use abi_stable::library::lib_header_from_path;
18
19pub use crate::api::*;
20#[doc(hidden)]
22pub use crate::proxy::PluginMod_Ref;
23
24#[macro_export]
39macro_rules! export_plugin {
40 ($plugin_constructor:expr $(,)?) => {
41 #[allow(clippy::drop_non_drop)] #[::abi_stable::export_root_module]
46 pub fn instantiate_root_module() -> $crate::PluginMod_Ref {
47 $crate::PluginMod_Ref::new(plugin_constructor)
48 }
49
50 #[allow(clippy::drop_non_drop)] #[::abi_stable::sabi_extern_fn]
53 pub fn plugin_constructor() -> $crate::PluginProxy {
54 $crate::PluginProxy::new($plugin_constructor)
55 }
56 };
57}
58
59impl PluginProxy {
60 pub fn from_path(path: impl AsRef<Path>) -> Result<Self, arci::Error> {
62 let path = path.as_ref();
63
64 let header = lib_header_from_path(path).map_err(anyhow::Error::from)?;
65 let root_module = header
66 .init_root_module::<PluginMod_Ref>()
67 .map_err(anyhow::Error::from)?;
68
69 let plugin_constructor = root_module.plugin_constructor();
70 let plugin = plugin_constructor();
71
72 Ok(plugin)
73 }
74}
75
76impl fmt::Debug for PluginProxy {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 f.debug_struct("PluginProxy").finish()
79 }
80}
81
82static TOKIO: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| {
84 std::thread::Builder::new()
85 .name("openrr-plugin/tokio".to_owned())
86 .spawn(move || TOKIO.block_on(std::future::pending::<()>()))
87 .unwrap();
88 tokio::runtime::Builder::new_multi_thread()
89 .enable_all()
90 .build()
91 .expect("cannot start tokio runtime")
92});