#[macro_export]
macro_rules! export_plugin {
($ty:ty) => {
#[unsafe(no_mangle)]
pub extern "C" fn linsight_plugin_abi_version() -> u32 {
$crate::LINSIGHT_PLUGIN_ABI_VERSION
}
#[$crate::stabby::export]
pub extern "C" fn linsight_plugin_v6() -> $crate::stabby::dynptr!(
$crate::stabby::boxed::Box<dyn $crate::LinsightPlugin + Send + Sync>
) {
let boxed: $crate::stabby::boxed::Box<$ty> =
$crate::stabby::boxed::Box::new(<$ty as Default>::default());
boxed.into()
}
};
(
$ty:ty,
metadata: {
plugin_id: $plugin_id:expr,
display_name: $display_name:expr,
version: $version:expr $(,)?
} $(,)?
) => {
#[unsafe(no_mangle)]
pub extern "C" fn linsight_plugin_abi_version() -> u32 {
$crate::LINSIGHT_PLUGIN_ABI_VERSION
}
#[$crate::stabby::export]
pub extern "C" fn linsight_plugin_metadata_v1() -> $crate::RPluginMetadata {
$crate::PluginMetadata {
plugin_id: $plugin_id.into(),
display_name: $display_name.into(),
version: $version.into(),
}
.into()
}
#[$crate::stabby::export]
pub extern "C" fn linsight_plugin_v6() -> $crate::stabby::dynptr!(
$crate::stabby::boxed::Box<dyn $crate::LinsightPlugin + Send + Sync>
) {
let boxed: $crate::stabby::boxed::Box<$ty> =
$crate::stabby::boxed::Box::new(<$ty as Default>::default());
boxed.into()
}
};
}
#[cfg(test)]
mod tests {
use linsight_core::SensorId;
use stabby::result::Result as SResult;
use crate::{
LinsightPlugin, PluginCtx, PluginError, PluginManifest, RInitResult, RPluginCtx,
RPluginError, RPluginManifest, RReading, RSampleResult, RSensorId, host_init, host_sample,
};
#[derive(Default)]
struct EchoPlugin;
impl LinsightPlugin for EchoPlugin {
extern "C-unwind" fn init(&self, _ctx: &RPluginCtx) -> RInitResult {
let m = PluginManifest {
plugin_id: "echo".into(),
display_name: "Echo".into(),
version: "0.0.1".into(),
sensors: vec![],
devices: vec![],
};
let r: RPluginManifest = m.into();
SResult::Ok(r)
}
extern "C-unwind" fn sample(&self, _: RSensorId) -> RSampleResult {
let r: RReading = linsight_core::Reading::Scalar(1.0).into();
SResult::Ok(r)
}
}
#[test]
fn host_init_round_trips() {
let p = EchoPlugin;
let m = host_init(&p, &PluginCtx::default()).unwrap();
assert_eq!(m.plugin_id, "echo");
}
#[test]
fn host_sample_round_trips() {
let p = EchoPlugin;
let r = host_sample(&p, &SensorId::new("anything")).unwrap();
assert!(matches!(r, linsight_core::Reading::Scalar(v) if v == 1.0));
let _ = std::any::TypeId::of::<PluginError>();
let _ = std::any::TypeId::of::<RPluginError>();
}
}