Hi there, I'm new to the rust programming language and recently created my first project without the use of a tutorial. I decided to make an app that, when supplied with a path (to either an mp3 file or directory) would either play this file with rodio or, if given a directory, search that directory (optionally recursively) to find all mp3 files within that directory, which I then add to the rodio sink by looping through the returned vector. The code I wrote for this is recursive directory search is below. I'm not super familiar with rust best practice or whether this approach requires the file_paths vector to be copied multiple times.
use std::path::Path;
use log::warn;
fn walk_dir(
dir: &Path,
file_paths: &mut Vec<String>,
recursive: bool,
) -> Result<Vec<String>, std::io::Error> {
for entry in std::fs::read_dir(dir)? {
let entry = entry?;
let file_path = entry.path();
if recursive && file_path.is_dir() {
walk_dir(&file_path, file_paths, recursive)?;
} else if file_path.extension().and_then(std::ffi::OsStr::to_str) == Some("mp3") {
// This could be a lossy conversion. Read the docs about this
file_paths.push(file_path.display().to_string());
} else {
warn!(
"Found non-mp3 file or directory {}",
file_path.display().to_string()
);
}
}
// Should we be converting to a vec here?
Ok(file_paths.to_vec())
}
pub(crate) fn get_file_paths(dir: &Path, recursive: bool) -> Result<Vec<String>, std::io::Error> {
match dir.is_dir() {
// Return a vector containing all audio files in the dir
true => {
let mut file_paths: Vec<String> = Vec::new();
walk_dir(dir, &mut file_paths, recursive)
}
// Return a vector of size one
false => Ok(Vec::from([dir.display().to_string()])),
}
}