I'm trying to rewrite the following function using iterators but I'm not sure how to do it.
fn load_cheats<P: AsRef<Path>>(path: P) -> Result<Vec<Cheat>> {
let mut cheats = Vec::new();
for entry in std::fs::read_dir(path)? {
let entry = entry?.path();
if entry.is_file() {
let data = std::fs::read_to_string(entry)?;
cheats.push(data.parse()?);
}
}
Ok(cheats)
}
I got it working but only if I use unwrap
on the results which isn't good.
fn load_cheats<P: AsRef<Path>>(path: P) -> Result<Vec<Cheat>> {
Ok(std::fs::read_dir(path)?
.map(|e| e.unwrap().path())
.filter(|p| p.is_file())
.map(|p| std::fs::read_to_string(p).unwrap())
.map(|data| data.parse().unwrap())
.collect())
}
I can't figure out how to remove the unwrap
s when chaining multiple map
s and filter
s that return Result
s.
I saw one reply on StackOverflow where there were multiple collect
s in the chain but this seems more complicated than it needs to be: rust - How to handle Result in flat_map - Stack Overflow
Another answer was to move the Result
out of the iterator loop which looks goo but only seems to work when you're not chaining multiple iterators: rust - How do I stop iteration and return an error when Iterator::map returns a Result::Err? - Stack Overflow