use anyhow::{Context as _, Result};
use libloading::Library;
use super::PluginStep;
pub struct PluginLoader {
_libraries: Vec<Library>,
}
impl PluginLoader {
pub fn new() -> Self {
Self {
_libraries: Vec::new(),
}
}
pub fn load_plugin(path: &str) -> Result<Box<dyn PluginStep>> {
unsafe {
let lib =
Library::new(path).with_context(|| format!("Failed to load library at '{path}'"))?;
let constructor: libloading::Symbol<unsafe extern "C" fn() -> *mut dyn PluginStep> =
lib.get(b"create_plugin\0").with_context(|| {
format!("Library '{path}' does not export 'create_plugin' symbol")
})?;
let raw = constructor();
if raw.is_null() {
anyhow::bail!("Plugin constructor in '{path}' returned null pointer");
}
std::mem::forget(lib);
Ok(Box::from_raw(raw))
}
}
}
impl Default for PluginLoader {
fn default() -> Self {
Self::new()
}
}