use crate::inventory::{ForeignInventory, Inventory, PluginId};
pub type RegisterTrampolineFn = extern "C" fn(i64, *const u8);
pub trait PluginInfo {
fn id() -> PluginId;
fn register(inventory: &mut impl Inventory);
#[must_use]
fn inventory() -> ForeignInventory {
let mut inventory = ForeignInventory::new();
Self::register(&mut inventory);
inventory
}
}
pub trait Plugin: Sized {
fn load_from(loader: impl Fn(&str) -> *const u8) -> Result<Self, PluginLoadError>;
fn register_trampoline_fn(&self) -> RegisterTrampolineFn;
}
pub trait Loader {
fn load_plugin<T: Plugin>(&self) -> Result<T, PluginLoadError>;
}
#[derive(Debug)]
pub enum PluginLoadError {
SymbolNotFound(String),
LoadFailed(String),
}
impl std::fmt::Display for PluginLoadError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::SymbolNotFound(name) => write!(f, "symbol not found: {name}"),
Self::LoadFailed(msg) => write!(f, "failed to load plugin: {msg}"),
}
}
}
impl std::error::Error for PluginLoadError {}