How to allow for plugins as separate crates

72 Views Asked by At

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.

0

There are 0 best solutions below