Hello guys, i am new to Rust. And i am trying to make something like "Callback to mutable self"
Is there a way to send a mutable borrowed self to a callback
use std::cell::RefCell;
use std::rc::Rc;
#[derive(Clone)]
pub struct Callbacks {
callbacks: Vec<Rc<RefCell<dyn FnMut(&mut App)>>>,
}
impl Callbacks {
pub fn new() -> Self {
Callbacks {
callbacks: Vec::new(),
} /*@*/
}
pub fn register<F: FnMut(&mut App) + 'static>(&mut self, callback: F) {
let cell = Rc::new(RefCell::new(callback));
self.callbacks.push(cell); /*@*/
}
pub fn call(&mut self, val: &mut App) {
for callback in self.callbacks.iter() {
let mut closure = callback.borrow_mut();
(&mut *closure)(val);
}
}
}
struct App {
age: u32,
events: std::rc::Rc<std::cell::RefCell<Callbacks>>,
}
impl App {
fn new() -> App {
App {
age: 23,
events: Rc::new(RefCell::new(Callbacks::new())),
}
}
fn insert<F: FnMut(&mut App) + 'static>(&mut self, event: F) {
self.events.borrow_mut().register(event);
}
fn call_events(&mut self) {
self.events.borrow_mut().call(self);
}
}
fn main() {
let mut app = App::new();
app.age = 100;
println!("Age is {}", app.age);
app.insert(|val| {
val.age = 123;
println!("Hello {}", val.age);
});
app.call_events();
}
And i got this
Compiling playground v0.0.1 (/playground)
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
--> src/main.rs:48:9
|
48 | self.events.borrow_mut().call(self);
| ------------------------^^^^^^^^^^^- ... and the immutable borrow might be used here, when that temporary is dropped and runs the destructor for type `std::cell::RefMut<'_, Callbacks>`
| |
| mutable borrow occurs here
| immutable borrow occurs here
| a temporary with access to the immutable borrow is created here ...
error: aborting due to previous error
For more information about this error, try `rustc --explain E0502`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.
It would be great if someone could help me with my code.