I'm experimenting with a dynamic registry of different "object" types that all implement a common interface "Obj". I'd like to be able to register them and later create instances depending on user configuration.
This is what I've come up with:
use std::collections::HashMap;
trait Obj {
fn create(name: &str) -> Box<Obj>;
}
struct ExampleObj {
name: String,
}
impl Obj for ExampleObj {
fn create(name: &str) -> Box<Obj> {
Box::new(ExampleObj { name: name.into() })
}
}
type Constructor = Fn(&str) -> Box<Obj>;
struct ObjRegistry<'a> {
map: HashMap<String, &'a Constructor>,
}
impl<'a> ObjRegistry<'a> {
fn new() -> ObjRegistry<'a> {
ObjRegistry { map: HashMap::new() }
}
fn register(&mut self, clsname: &str, ctor: &'a Constructor) {
self.map.insert(clsname.into(), ctor);
}
}
fn main() {
let mut reg = ObjRegistry::new();
reg.register("test", &ExampleObj::create);
}
but it doesn't compile because "the trait Obj is not object-safe". How to work around that?
I've also tried making create
a free function, but it seems to make the compiler exit with SIGILL...