use std::{
fs,
path::{Path, PathBuf},
};
use crate::error::{MtagError, MtagResult};
pub fn scan_audio_files(root: &Path) -> MtagResult<Vec<PathBuf>> {
let mut files = Vec::new();
visit_folder(root, &mut files)?;
files.sort();
Ok(files)
}
fn visit_folder(folder: &Path, files: &mut Vec<PathBuf>) -> MtagResult<()> {
let entries = fs::read_dir(folder).map_err(|source| MtagError::ReadDirectory {
path: folder.to_path_buf(),
source,
})?;
for entry in entries {
let entry = entry.map_err(|source| MtagError::ReadDirectory {
path: folder.to_path_buf(),
source,
})?;
let path = entry.path();
if path.is_dir() {
visit_folder(&path, files)?;
} else if path.is_file() && is_audio_file(&path)? {
files.push(path);
}
}
Ok(())
}
fn is_audio_file(path: &Path) -> MtagResult<bool> {
let kind = infer::get_from_path(path).map_err(|source| MtagError::InspectFileType {
path: path.to_path_buf(),
source,
})?;
Ok(kind.is_some_and(|kind| kind.mime_type().starts_with("audio/")))
}