DaKoller
DaKoller

Reputation: 21

Rust File Tree move occurs because `subtree` has type `trees::Tree<PathBuf>`, which does not implement the `Copy` trait

i am trying to make a simple tauri Program where i have a Filetree of all Files and sub files of a chosen directory. I have not got many experience in Rust and ran into a problem with Ownerships.

Code

use std::fs;
use std::path::PathBuf;
use trees::Tree;

//FileTree
//https://docs.rs/crate/file_tree/0.1.1
fn main() {
    let path = PathBuf::from("MyPath...");
    let tree = Tree::new(path);
    
    build_tree(tree);
}

fn build_tree( mut tree:Tree<PathBuf>){
    
    let path = tree.front().unwrap().data();
    for entry in fs::read_dir(path).unwrap() {
        let entry = entry.unwrap();
        let subpath = entry.path();
        if subpath.is_dir() {
            let subtree = Tree::new(subpath);
            build_tree(subtree);
            tree.push_back(subtree);
        } else {
            tree.push_back(Tree::new(subpath));
        }
    }
    tree;
}

This is what i figured out so far but in the line: tree.push_back(subtree);

I got following Error

error[E0382]: use of moved value: subtree

  --> src\main.rs:23:28
   |
21 |             let subtree = Tree::new(subpath);
   |                 ------- move occurs because `subtree` has type `trees::Tree<PathBuf>`, which does not implement the `Copy` trait
22 |             build_tree(subtree);
   |                        ------- value moved here
23 |             tree.push_back(subtree);
   |                            ^^^^^^^ value used here after move

What i tried

I tried to make subtree mutable but it didn't work either because it says mut is not necessary

Also i already tried to use the Filetree crate of Rust but it was not exectely what i was looking for.

Someone got other Ideas how to Implement a Filetree in Rust or Tauri?

Upvotes: 0

Views: 354

Answers (1)

Jeremy Meadows
Jeremy Meadows

Reputation: 2581

You are trying to mutate a tree in your build_tree function, but since the function is taking ownership of whatever you pass in, you get the value used here after move error afterwards. To allow a function to mutate a variable and the variable still exist afterwards, you should instead pass in a mutable reference to the tree:

use std::fs;
use std::path::PathBuf;
use trees::Tree;

fn main() {
    let path = PathBuf::from("MyPath...");
    let mut tree = Tree::new(path);
    
    build_tree(&mut tree);
}

fn build_tree(tree: &mut Tree<PathBuf>) {
    let path = tree.front().unwrap().data();

    for entry in fs::read_dir(path).unwrap() {
        let entry = entry.unwrap();
        let subpath = entry.path();

        if subpath.is_dir() {
            let mut subtree = Tree::new(subpath);
            build_tree(&mut subtree);
            tree.push_back(subtree);
        } else {
            tree.push_back(Tree::new(subpath));
        }
    }
}

Notice also that you need to change some variable declarations to use let mut so that the compiler allows a mutable reference (&mut) to that variable to be used.

This can also be done by taking ownership and returning a new value, but this method looks a little closer to what you had originally.

Upvotes: 1

Related Questions