I'm trying to implement a Dispatcher
that holds a HashMap
of closures which contain methods from other structs. The Dispatcher
should be able to be passed around as it represents one event handler with a state for many clients.
With Dispatcher::add_method
, it should be possible to add new closures to the HashMap
:
struct Dispatcher<'a> {
methods: HashMap<String, Box<dyn FnMut(i32) + 'a>>,
}
impl<'a> Dispatcher<'a> {
...
pub fn add_method(&mut self, name: String, method: impl FnMut(i32) + 'a) {
self.methods.insert(name, Box::new(method));
}
...
}
An example of a struct that uses the Dispatcher
and adds new methods to it:
struct Example {
num: i32,
}
impl Example {
pub fn init<'a>(&'a mut self, dispatcher: &'a mut Dispatcher<'a>) {
dispatcher.add_method("test".to_string(), move |num| {
self.num = num;
});
}
}
I don't know how to initialize the Example
to add the closures to the Dispatcher
. I'm trying this but the result is a compilation error.
struct Handler<'a>{
example: Example,
dispatcher: Dispatcher<'a>
}
impl<'a> Handler<'a>{
fn new() -> Self {
let mut dispatcher = Dispatcher::new();
let mut example = Example::new();
example.init(&mut dispatcher);
Handler{
example: example,
dispatcher: dispatcher,
}
}
}
I understand that I'm trying to move out an borrowed value, but I have to borrow the Dispatcher
for the init
method of the Example
. How should I do it otherwise?
error[E0515]: cannot return value referencing local variable `dispatcher`
--> src/lib.rs:46:9
|
44 | example.init(&mut dispatcher);
| --------------- `dispatcher` is borrowed here
45 |
46 | / Handler {
47 | | example: example,
48 | | dispatcher: dispatcher
49 | | }
| |_________^ returns a value referencing data owned by the current function
error[E0515]: cannot return value referencing local variable `example`
--> src/lib.rs:46:9
|
44 | example.init(&mut dispatcher);
| ------- `example` is borrowed here
45 |
46 | / Handler {
47 | | example: example,
48 | | dispatcher: dispatcher
49 | | }
| |_________^ returns a value referencing data owned by the current function
error[E0505]: cannot move out of `example` because it is borrowed
--> src/lib.rs:47:22
|
39 | impl<'a> Handler<'a> {
| -- lifetime `'a` defined here
...
44 | example.init(&mut dispatcher);
| ------- borrow of `example` occurs here
45 |
46 | / Handler {
47 | | example: example,
| | ^^^^^^^ move out of `example` occurs here
48 | | dispatcher: dispatcher
49 | | }
| |_________- returning this value requires that `example` is borrowed for `'a`
error[E0505]: cannot move out of `dispatcher` because it is borrowed
--> src/lib.rs:48:25
|
39 | impl<'a> Handler<'a> {
| -- lifetime `'a` defined here
...
44 | example.init(&mut dispatcher);
| --------------- borrow of `dispatcher` occurs here
45 |
46 | / Handler {
47 | | example: example,
48 | | dispatcher: dispatcher
| | ^^^^^^^^^^ move out of `dispatcher` occurs here
49 | | }
| |_________- returning this value requires that `dispatcher` is borrowed for `'a`