I'm trying to build a rust program. Part of it involves a function that:
Read a directory and collects the files paths into a vector => Could lead to some error if it can't read the directory
Chooses a random file from the list => Could be none, if the directory is empty
Reads the content of the file to a string => Could lead to an error if it Can´t read the file
Currently it works with unwraping:
fn template(dir: &Path) -> Result<String, io::Error> {
let mut rng = thread_rng();
let files = fs::read_dir(dir).unwrap();
let file = files.choose(&mut rng).unwrap().unwrap();
let text = fs::read_to_string(file.path());
return text
}
I even need to call unwrap twice at some point
I've tried a few different approaches to remove these unwraps but couldn't get it to work, anyone can help me or point in the right directon?
Thank you. Much simpler than the solution I had so far:
fn template(dir: &Path) -> Result<String, io::Error> {
let files = fs::read_dir(dir)?
.map(|res| res.map(|e| e.path()))
.collect::<Result<Vec<_>, io::Error>>()?;
let file = files
.choose(&mut rng)
.ok_or_else(|| io::Error::new(ErrorKind::NotFound, "Directory is empty"))?;
let text = fs::read_to_string(file)?;
Ok(text)
}
No need to collect into a vector, and the nested maps were really bugging me. I got it from an example of the read_dir docs but I can't quite understand it.