Search code examples
rustborrow-checker

Rust borrowing with loop and Vec


I simply try to build a kind of tree: having one root node and then want to add nodes as subnodes to the root node. It runs into this error and I cannot get my head around what is going wrong.

enter image description here

#[derive(Clone)]
pub struct Node {
    id: String,
    file: FileContent, 
    nodes: Vec<Node>,
}

impl Node {
    pub fn new(file:FileContent) -> Self {
        Self {
            id: file.path.clone(),
            file: file.clone(),
            nodes:Vec::<Node>::new(),
        }
    }

    pub fn add(mut self, node: Node) -> Self{
        self.nodes.push(node.clone());
        self
    }
}

#[derive(Clone)]
pub struct FileContent {
    path: String,
    length: usize,
    content_type: String,
}

pub fn create_test_file_content() -> Vec<FileContent> {
    let mut file_content = Vec::<FileContent>::new();
    file_content.push(FileContent {path:String::from("r/a1/a2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content.push(FileContent {path:String::from("r/b1/ba2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content.push(FileContent {path:String::from("r/b1/bb2"),length: 1,content_type: String::from("DIRECTORY"),});
    file_content
}

fn main() {

    let filecontent = create_test_file_content();
    
    let root = Node::new(FileContent {path:String::from("root"),length: 1,content_type: String::from("DIRECTORY")});

    for fc in filecontent {
        let node = Node::new(fc);
        root.add(node);
    }

}

When I follow the suggestion of cloning the root node, then it works but why should I do this? 'root' is still in the same scope and only struct member 'nodes'-changes.

Many thanks


Solution

  •  pub fn add(&mut self, node: Node) {
            self.nodes.push(node);
     }
    

    You may want to borrow self as a mutable reference and directly push the nodes. I am not sure why you are returning self from add() method.

    let mut root = Node::new(FileContent {path:String::from("root"),length: 1,content_type: String::from("DIRECTORY")});
    

    You should also declare root as mutable since you are mutating it