I'm trying to understand how to do some simple things in Rust, but I keep ending up fighting the borrow checker and I'm not sure why. I've written a simple function where you pass it a filename and it gives you the path to that file in your home directory.
Here's the program:
use std::env;
fn filename_in_homedir(filename: &str) -> Option<&str> {
let mut homedir = match env::home_dir() {
None => return None,
Some(p) => p
};
homedir.push(filename);
homedir.to_str()
}
fn main() {
match filename_in_homedir(".ssh/id_rsa.pub") {
Some(s) => println!("{}", s),
None => println!("Oops can't get it")
};
}
When I try building it I get this error:
$ cargo build
Compiling homedir-test v0.1.0 (file:///home/user/code/homedir-test)
src/main.rs:9:5: 9:12 error: `homedir` does not live long enough
src/main.rs:9 homedir.to_str()
^~~~~~~
src/main.rs:3:56: 10:2 note: reference must be valid for the anonymous lifetime #1 defined on the block at 3:55...
src/main.rs:3 fn filename_in_homedir(filename: &str) -> Option<&str> {
src/main.rs:4 let mut homedir = match env::home_dir() {
src/main.rs:5 None => return None,
src/main.rs:6 Some(p) => p
src/main.rs:7 };
src/main.rs:8 homedir.push(filename);
...
src/main.rs:7:7: 10:2 note: ...but borrowed value is only valid for the block suffix following statement 0 at 7:6
src/main.rs: 7 };
src/main.rs: 8 homedir.push(filename);
src/main.rs: 9 homedir.to_str()
src/main.rs:10 }
error: aborting due to previous error
Could not compile `homedir-test`.
I don't understand why doesn't work. If env::home_dir()
fails, the function returns None
. If it succeeds, then the mutable variable homedir gets its value (which is a std::path::PathBuf
). At this point, the homedir
variable should be owned by the filename_in_homedir
scope. The next line modifies homedir
to add the filename to the end, and this works fine. The final line, calling .to_str()
, returns an Option<&str>
itself.
Since I'm ultimately returning a &str
that's pointing somewhere inside homedir
, maybe when the filename_in_homedir
scope ends and homedir
gets deleted, that &str
does too, which is why it's throwing this error?
How do I modify this function to work properly, and what am I doing wrong?