I have a rust crate (that is published on crates.io).
The functionality that crate provides is also available as a command line utility,
that can be installed using cargo install
.
This command line application accepts plugins using the following basic mechanism:
use libloading::Library;
pub trait Plugin {
fn plugin_fn_1(&self);
fn plugin_fn_2(&self);
// ...
}
fn main() {
let plugin_paths: Vec<OsString> = Vec::new(); //???
let mut plugin_registry = Vec::new();
for path in plugin_paths {
unsafe {
let lib = Box::leak(Box::new(Library::new(path).unwrap()));
let plugin_entry_point = lib
.get::<libloading::Symbol<
unsafe extern "C" fn() -> &'static mut dyn Plugin,
>>(b"plugin_entry_point")
.unwrap();
plugin_registry.push(plugin_entry_point());
}
}
for plugin in &plugin_registry {
plugin.plugin_fn_1();
}
// ...
}
I would like plugins to be individual crates (publishable on crates.io), and
installable using cargo install
, without any additional user specified arguments.
How can the code above find the installed plugins (to fill the plugin_paths
variable of the sample code above) in a cross platform way? (I only care about Linux, Mac and Windows).
Is there some established / conventional mechanism to do this?
I guess that either the plugins have to somehow register themselves during their own cargo install
, or my binary has to scan some folder that it knows that the plugins will reside in.
I wouldn't mind either way, but I would like to avoid recursively searching through lots of directories every time the binary is launched.