this post was submitted on 22 Mar 2024
15 points (100.0% liked)

Rust Programming

8183 readers
36 users here now

founded 5 years ago
MODERATORS
 

I have a plugin trait that includes some heavy types that would be almost impossible to wrap into a single API. It looks like this:

pub struct PluginContext<'a> {
    pub query: &'a mut String,
    pub gl_window: &'a GlutinWindowContext,
    flow: PluginFlowControl,
    pub egui_ctx: &'a Context,
    disable_cursor: bool,
    error: Option<String>,
}
pub trait Plugin {
    fn configure(&mut self, builder: ConfigBuilder) -> Result<ConfigBuilder, ConfigError> {
        Ok(builder)
    }
    fn search(&mut self, ui: &mut Ui, ctx: &mut PluginContext<'_>);
    fn before_search(&mut self, _ctx: &mut PluginContext<'_>) {}
}

Here is what I considered:

  1. Keeping all plugins in-repo. This is what I do now, however I'd like to make a plugin that would just pollute the repository. So I need another option that would keep the plugins' freedom as it is right now, but with the possibility to move the plugin out to a separate repository.
  2. I tried to look into dynamic loading, and since rust doesn't have a stable ABI, I'm okay with restricting the rust versions for the plugin ecosystem. However, I don't think it's possible to compile this complex API into a dynamic lib and load it safely.
  3. I'm also ok with recompiling the app every time I need a new plugin, but I would like to load these plugins automatically, so I don't want to change the code every time I need a new plugin. For example, I imagine loading all plugins from a folder. Unfortunately, I didn't find an easy solution for this neither. I think I will write a build macro that checks the ~/.config/myapp/plugins and include all of them into the repo.

Do you have any better ideas, suggestions? Thanks in advance.

(For context, this the app I'm writing about: https://github.com/fxdave/vonal-rust)

you are viewing a single comment's thread
view the rest of the comments
[–] Vorpal 1 points 8 months ago* (last edited 8 months ago)

So there is a couple of options for plugins in Rust (and I haven't tried any of them, yet):

  • Wasm, supposedly https://extism.org/ makes this less painful.
  • libloading + C ABI
  • One of the two stable ABI crates (stabby or abi_stable) + libloading
  • If you want to build them into your code base but not have to update a central list there is linkme and inventory.
  • An embedded scripting language might also be a (very different) option. Something like mlua, rhai or rune.

I don't know if any of these suit your needs, but at least you now have some things to investigate further.