use std::{fs, io};
use std::path::Path;
fn main() -> io::Result<()> {
let books_vector = vec!["/home/pichi/books/"];
// var store result
let mut genre_vector: Vec<&str> = Vec::new();
// .iter over books_vector
for f in books_vector.iter() {
for entry in fs::read_dir(&f)? {
let genre = entry?.path();
let genre_str = genre.to_str().unwrap(); // original name
//println!("Genre folders: {:?} ", genre.file_stem().unwrap());
genre_vector.push(&genre_str); // -> ERROR !!!
}
}
println!("Genre in vector: {:?} ", genre_vector);
Ok(())
}
OUTPUT:
error[E0597]: genre does not live long enough
borrowed value does not live long enough
genre_vector.push(&genre_str);
| ----------------------------- borrow later used here
21 | }
| - genre dropped here while still borrowed
&str is not a string itself, but a temporary permission to view some actual string stored somewhere else. In your case there is no such string to borrow — you're not keeping genre anywhere, and letting it be implicitly destroyed at the end of its scope. When a variable goes out of scope, all loans of it are invalid and can't be kept.
You won't be able to make Vec<&str> incrementally like that. This type has wrong type of ownership for this code. You should be using Vec<String> instead. This is a vec that actually contains (owns) strings.
genre is a path that may not be compatible with UTF-8. to_str() lets you view the path temporarily as a &str. To make it owned, you can use to_string() that gives you a self-contained String that doesn't borrow from any other local variable.
let genre_str = genre.to_str().unwrap().to_string();
genre_vector.push(genre_str);
There's a slightly more efficient way for converting PathBuf to String: genre.into_os_string().into_string().expect("UTF-8")