Hi all.

I want to develop a plugin system within my program, and I have a trait that functions defined by plugins should implement.

Currently, my code gets all the functions in a HashMap and then calls them by their name. Problem is, I have to create that hashmap myself by inserting every function myself.

I would really appreciate it if there was a way to say, suppose, all pub members of mod functions:: that implement this trait PluginFunction call register(hashmap) function. So as I add more functions as mod in functions it’ll be automatically added on compile.

Pseudocode:

Files:

src/
├── attrs.rs
├── functions
│   ├── attrs.rs
│   ├── export.rs
│   └── render.rs
├── functions.rs
├── lib.rs

Basically, in mod functions I want:

impl AllFunctions{
    pub fn new() -> Self {
       let mut functions_map = HashMap::new();[[
       register_all!(crate::functions::* implementing PluginFunction, &mut functions_map);
       Self { function_map }
  }
}

Right now I’m doing:

impl AllFunctions{
    pub fn new() -> Self {
       let mut functions_map = HashMap::new();[[
       crate::functions::attrs::PrintAttr{}.register(&mut functions_map);
       crate::functions::export::ExportCSV{}.register(&mut functions_map);
       crate::functions::render::RenderText{}.register(&mut functions_map);
       // More as I add more functions
       Self { function_map }
  }
}
  • @thevoidzeroOP
    link
    27 days ago

    Thank you. I just put the call with !, I don’t necessarily want a macro solution. Any solution is acceptable, my requirement is that I can just keep adding more mods with functions in src/functions/ and not have to register each function.

    Inventory seems like the solution I am looking for. Although in my case, instead of collecting different values of the same type, I want to collect different types that all have same trait. But maybe I can make a temporary struct with Box<dyn _> member to collect it if trying to collect it directly doesn’t work. I do not plan to support WASM. I am planning to make C/C++ and Python API for the libraries though, so if it has problems with them, then I might have a problem.

    • @[email protected]
      link
      fedilink
      26 days ago

      Maybe keep maintaining the HashMap you have now and use one of these less portable mechanisms in a test to alert you when you forgot to register one?

      • @thevoidzeroOP
        link
        16 days ago

        That seems like a good compromise if I don’t find something better. Thank you.

        I’m hoping to make it easy for people to add more functions, that’s why I want minimal code change required to add more functions.