Mathias DA COSTA
Mathias DA COSTA

Reputation: 13

Get reference to a specific struct in a Vector to modify it

I'm starting my first project in Rust. I try to make a Zwave crate.

I'm stuck with the problem of ref sharing. For now, the code is divided in 3 structs:

Network, which contains global Zwave network information:

struct Network{
    name: &'static str,
    home_id: u32,
    nodes: Vec<Node>,
}

A Node structure which contains information of a specific node:

struct Node{
    pub name: &'static str,
    home_id: u32,
    node_id: u8,
    devices: Vec<Device>,
}

And a device storing data about sensor or other Zwave device:

struct Device{
    name: &'static str,
    class: DeviceClass,
}

What I'm trying to do is get the reference of a specific node in order to modify devices in it (Add, remove...), but it always lead to the same error when I try to add device after getting reference of the node: Cannot borrow as mutable

The add_device function looks like this:

pub fn add_device(&mut self, name: &'static str ) -> Result<bool, &'static str>{
    self.devices.push(Device::new(name)?);
    Ok(true)
}

This is how I try to get reference in Network struct:

pub fn get_node(&self, node_name : String ) -> Result<&Node, &'static str>{
    for node in &self.nodes{
        if node.name == node_name{
            return Ok(node);
        }
    }
    Err("Node not find")
}

I have try with Mutex, Rc, tried to implement copy/clone but never reach what I want. Can you help me?

Up: The error message I'm getting is this when I try to add a new Device to the Node I have the reference :

error[E0507]: cannot move out of `*node` which is behind a shared reference
  --> src\main.rs:14:5
   |
14 |     node.add_device("testDevice").expect("Couldn't add device");
   |     ^^^^^------------------------
   |     |    |
   |     |    `*node` moved due to this method call
   |     move occurs because `*node` has type `Node`, which does not implement the `Copy` trait
   |
note: this function takes ownership of the receiver `self`, which moves `*node`
  --> src\main.rs:94:23
   |
94 |     fn add_device(mut self, name: &'static str) -> Result<bool, &'static str> {
   |                       ^^^^

Upvotes: 0

Views: 72

Answers (1)

kxin
kxin

Reputation: 1

consider using (&mut self) as function argument and the return type to a mutable reference to Node (Result<&mut Node, &'static str>) and then you can iterate the nodes Vec with iter_mut() to get a mutable reference to the nodes like:

for node in self.nodes.iter_mut() {
    if node.name == node_name{
        return Ok(node);
    }
}
Err("Node not find")

and that should work for you

Upvotes: 0

Related Questions