Pattern matching and mutability

Hello, I read previous posts about borrowed content but I can’t understand how to solve this:

struct Image {
    x: u32,
    y: u32,
}
struct RenderData {
    image: Image,
}

impl RenderData {
    fn new(image: Image) -> RenderData {
        RenderData { image }
    }
}

enum Cell {
    Object(RenderData),
}

struct Controller {
    objects: Vec<Cell>,
    selected: Option<Cell>,
}

impl Controller {
    fn new() -> Controller {
        Controller {
            objects: Vec::new(),
            selected: None,
        }
    }

    fn select_image(&mut self, image: Image) {
        self.selected = Some(Cell::Object(RenderData::new(image)));
    }

    fn add_image(&mut self) {
        match self.selected.as_ref() {
            Some(cell) => {
                self.objects.push(*cell);
                self.selected = None;
            }
            None => {}
        }
    }
}

The method add_image generates two errors:

error[E0507]: cannot move out of borrowed content
|
39 | self.objects.push(*cell);
| ^^^^^ cannot move out of borrowed content

error[E0506]: cannot assign to self.selected because it is borrowed
|
37 | match self.selected.as_ref() {
| ------------- borrow of self.selected occurs here

40 | self.selected = None;
| ^^^^^^^^^^^^^^^^^^^^ assignment to borrowed self.selected occurs here

I understood why but not sure how to solve them.

Any help is appreciated!

for your case you want to take a look at Option::take.

    fn add_image(&mut self) {
        match self.selected.take() {
            Some(cell) => self.objects.push(cell),
            None => (),
        }
    }
2 Likes