Heya. I'm currently trying to figure out how a basic plugin system would like in Rust. I have the following code, but I'm getting errors over multiple mutable borrows which makes sense. However, how can I circumvent this? Code is on Rust Playground.
You could only borrow the other fields of Editor
in Custom
:
trait Custom {
fn update(&mut self, name: &mut String, position: &mut usize);
}
#[derive(Default)]
struct Editor {
name: String,
position: usize,
myeditor: Option<Box<dyn Custom>>,
}
impl Editor {
fn new() -> Self {
Self {
myeditor: Some(Box::new(MyEditor::default())),
..Self::default()
}
}
fn run(&mut self) {
loop {
if let Some(myeditor) = &mut self.myeditor {
myeditor.update(&mut self.name, &mut self.position);
}
}
}
}
#[derive(Debug, Default)]
struct MyEditor();
impl Custom for MyEditor {
fn update(&mut self, name: &mut String, position: &mut usize) {
*name = String::from("bruh");
println!("{}", name);
}
}
fn main() {
Editor::default().run();
}
You need to remove myeditor
from self
so that you don't keep borrowing self
. Since you already have myeditor
as an Option
, the easiest way is to take()
it:
if let Some(myeditor) = &mut self.myeditor.take() {
myeditor.update(self);
}
You need to then put myeditor
back in afterwards, but since its boxed, there's no cost to moving it each time.
1 Like
After changing the code to the following:
if let Some(myeditor) = &mut self.myeditor.take() {
myeditor.update(self);
self.myeditor = Some(Box::new(myeditor));
}
I get the following error:
error[E0277]: the trait bound `&mut Box<(dyn Custom + 'static)>: Custom` is not satisfied
--> src/main.rs:23:38
|
23 | self.myeditor = Some(Box::new(myeditor));
| ^^^^^^^^^^^^^^^^^^ the trait `Custom` is not implemented for `&mut Box<(dyn Custom + 'sta
tic)>`
|
= note: required for the cast to the object type `dyn Custom`
Why doesn't this work?
That doesn't work because you are trying to rebox myeditor
when putting it back in. I think you can remove the &mut
referencing in the if let
and deal with myeditor
as an owned value, then put it back without reboxing (though you do need the Some
).
Smooth solution. Thanks!