Please can somebody advise me on the following issue.
This is the simplified version of a program I'm trying to build:
trait CallbackHandler {
fn callback(&mut self);
}
struct CallbackRegistry<'a> {
handlers: Vec<&'a mut CallbackHandler>
}
impl<'a> CallbackRegistry<'a> {
pub fn new() -> CallbackRegistry<'a> {
CallbackRegistry {
handlers: Vec::with_capacity(10)
}
}
pub fn register(&mut self, handler: &'a mut CallbackHandler) {
self.handlers.push(handler);
}
}
struct Handler1<'a> {
registry: &'a mut CallbackRegistry<'a>
}
impl<'a> Handler1<'a> {
pub fn new(registry: &'a mut CallbackRegistry<'a>) -> Handler1<'a> {
Handler1 {
registry: registry
}
}
pub fn start(&'a mut self) {
// does not compile with "cannot borrow `*self` as mutable more than once at a time"
// self.registry.register(self);
}
}
impl<'a> CallbackHandler for Handler1<'a> {
fn callback(&mut self) {
}
}
The problem is in the line:
self.registry.register(self);
which understandably does not complie. The question is - what's the best way to go around this problem? One thing I can think of is that instead of storing a reference to registry as a member of Handler1 I should rather pass it as an argument to function "start". To me it's not very desirable as that would mean I have to pass a reference to registry all over the places in my application bloating the code and making unit testing more difficult. It would be also not nice from design perspective as the callers of start method do not necessarily need to know anything about "registry" .
I can imagine there will be lots of occasions where storing a borrowed pointer as a struct member would cause compilation problems which makes me think that common OOP techniques do not work very well in Rust. Is there anything I'm missing?