1

I want to create a struct containing a PathBuf (with an absolute path) and a &Path (with a relative path derived from that absolute path). Here is my attempt:

use std::path::{Path, PathBuf};

struct File<'a> {
    abs_path: PathBuf,
    rel_path: &'a Path,
}

impl<'a> File<'a> {
    fn new(abs_path: PathBuf, rel_path: &'a Path) -> File<'a> {
        File { abs_path, rel_path }
    }
}

fn main() {
    let abs_path = PathBuf::from("/path/to/file");
    let rel_path = abs_path.strip_prefix("/path").unwrap();
    let _file = File::new(abs_path, rel_path);
}

When I compile this, I get the following error:

error[E0505]: cannot move out of `abs_path` because it is borrowed
  --> src/main.rs:17:27
   |
16 |     let rel_path = abs_path.strip_prefix("/path").unwrap();
   |                    -------- borrow of `abs_path` occurs here
17 |     let _file = File::new(abs_path, rel_path);
   |                           ^^^^^^^^  -------- borrow later used here
   |                           |
   |                           move out of `abs_path` occurs here

I understand that I cannot transfer ownership of abs_path because I borrowed a reference to it when I created rel_path. I am attempting to link the two together inside the struct, by restricting the lifetime of rel_path. Can anyone tell me how to get both values into the struct?

Thanks!

Huw Walters
  • 1,888
  • 20
  • 20

1 Answers1

0

While there are ways to store a reference and a value together (raw pointers + Pin, Box + https://crates.io/crates/rental), the easiest thing to do would probably be to store the start and end index of the slice.

Solomon Ucko
  • 5,724
  • 3
  • 24
  • 45
  • 1
    Thanks, but in the end I went with a different solution. I'm writing a dir/ls style CLI tool, and I need to support either relative or absolute paths; and I decided to store the relative paths for display, and the absolute paths for sorting purposes. – Huw Walters Sep 04 '21 at 15:57