I am trying to build a simple game while learning rust. I have a hash map of 'Tiles' and a vector of 'Unit' with the trait 'Entity' within a struct called 'World'. Each 'Tile' has a reference to its adjacent tiles in a hash map and each 'Unit' has a reference to the tile it is currently occupying. The idea is that the 'World' struct owns everything.
struct World {
map: HashMap<(i32,i32), RwLock<Tile>>,
entities: Vec<Box<RwLock<Unit>>>,
}
struct Tile {
occupier: Option<Box<RwLock<Unit>>>,
position: (i32,i32),
adjacent: HashMap<Direction, RwLock<Tile>>,
}
struct Unit {
hp: u32,
position: RwLock<Tile>,
}
#[derive(PartialEq, Eq, Hash)]
enum Direction {
Up,
UpRight,
DownRight,
Down,
DownLeft,
UpLeft,
}
I'm trying to implement a method for Unit which moves the unit to an adjacent tile:
impl Unit {
fn move_entity(&mut self, dir: Direction) {
let mut tile = self.position.write().unwrap();
match tile.adjacent.get(&dir) {
Some(adjtile) => {
let ref mut occ = adjtile.write().unwrap().occupier;
match *occ {
Option::Some(_) => unimplemented!(), // tile already occupied, error
Option::None => {
*occ = Option::Some(tile.occupier.unwrap());
tile.occupier = Option::None;
},
}
},
None => unimplemented!(), // tile does not exist, error
}
}
}
However, the compiler complains that tile is borrowed in the match statement:
error[E0507]: cannot move out of borrowed content
--> src\main.rs:67:45
|
67 | *occ = Option::Some(tile.occupier.unwrap());
| ^^^^ cannot move out of borrowed content
error[E0502]: cannot borrow `tile` as mutable because it is also borrowed as immutable
--> src\main.rs:68:25
|
61 | match tile.adjacent.get(&dir) {
| ---- immutable borrow occurs here
...
68 | tile.occupier = Option::None;
| ^^^^ mutable borrow occurs here
...
73 | }
| - immutable borrow ends here
I'm not sure how to go about resolving this.