Improve the search_for
utilty function, and remove the recursive
This commit is contained in:
parent
eb78da0a71
commit
dfc198e55e
1 changed files with 45 additions and 19 deletions
62
src/utils.rs
62
src/utils.rs
|
@ -7,16 +7,38 @@ use std::path::Path;
|
|||
pub fn search_for(
|
||||
search_directory: &str,
|
||||
max_depth: u8,
|
||||
regx: &str,
|
||||
) -> Result<Option<String>, String> {
|
||||
// Search in the track directory.
|
||||
for entry in std::fs::read_dir(search_directory).map_err(|e| e.to_string())? {
|
||||
regx: ®ex::Regex,
|
||||
) -> std::io::Result<Option<String>> {
|
||||
let mut max_depth = max_depth;
|
||||
let mut search_directory = search_directory;
|
||||
|
||||
loop {
|
||||
if let Some(path) = search(search_directory, regx)? {
|
||||
return Ok(Some(path));
|
||||
}
|
||||
|
||||
if max_depth == 0 {
|
||||
break Ok(None);
|
||||
} else {
|
||||
// If the max depth is not reached, search in the parent directory.
|
||||
max_depth -= 1;
|
||||
search_directory = {
|
||||
let Some(parent) = Path::new(search_directory).parent() else { return Ok(None); };
|
||||
let Some(parent) = parent.to_str() else { return Ok(None); };
|
||||
parent
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn search(search_directory: &str, matcher: ®ex::Regex) -> std::io::Result<Option<String>> {
|
||||
for entry in std::fs::read_dir(search_directory)? {
|
||||
let Ok(entry) = entry else { continue; };
|
||||
let Ok(file_type) = entry.file_type() else { continue; };
|
||||
if file_type.is_file() {
|
||||
let Ok(file_name) = entry.file_name().into_string() else { continue; };
|
||||
// Check if the file name matches the regular expression.
|
||||
let matcher = regex::Regex::new(regx).map_err(|e| e.to_string())?;
|
||||
if matcher.is_match(&file_name) {
|
||||
let path = entry.path();
|
||||
let Some(path) = path.to_str() else { continue; };
|
||||
|
@ -24,15 +46,7 @@ pub fn search_for(
|
|||
}
|
||||
}
|
||||
}
|
||||
// If the max depth is reached, return `None`.
|
||||
if max_depth == 0 {
|
||||
Ok(None)
|
||||
} else {
|
||||
// If the max depth is not reached, search in the parent directory (recursively).
|
||||
let Some(parent) = Path::new(search_directory).parent() else { return Ok(None); };
|
||||
let Some(parent) = parent.to_str() else { return Ok(None); };
|
||||
search_for(parent, max_depth - 1, regx)
|
||||
}
|
||||
}
|
||||
|
||||
/// Replace all the placeholders in the template with their matching value.
|
||||
|
@ -101,7 +115,7 @@ mod tests {
|
|||
let cover_path = search_for(
|
||||
"tests/samples/Owl City/Cinematic/cover",
|
||||
1,
|
||||
r"cover|.\.jpg|.\.png",
|
||||
®ex::Regex::new(r"cover|.\.jpg|.\.png").unwrap(),
|
||||
);
|
||||
|
||||
assert_matches!(cover_path, Ok(Some(_)));
|
||||
|
@ -114,7 +128,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_search_for_cover_without_the_cover_key_world() {
|
||||
let cover_path = search_for(
|
||||
"tests/samples/Owl City/Cinematic/cover", 1, r".\.jpg|.\.png");
|
||||
"tests/samples/Owl City/Cinematic/cover",
|
||||
1,
|
||||
®ex::Regex::new(r".\.jpg|.\.png").unwrap(),
|
||||
);
|
||||
|
||||
assert_matches!(cover_path, Ok(Some(_)));
|
||||
assert_eq!(
|
||||
|
@ -126,7 +143,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_search_for_cover_without_the_cover_key_world_and_jpg() {
|
||||
let cover_path = search_for(
|
||||
"tests/samples/Owl City/Cinematic/cover", 1, r".\.png");
|
||||
"tests/samples/Owl City/Cinematic/cover",
|
||||
1,
|
||||
®ex::Regex::new(r".\.png").unwrap(),
|
||||
);
|
||||
|
||||
assert_matches!(cover_path, Ok(Some(_)));
|
||||
assert_eq!(
|
||||
|
@ -138,7 +158,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_search_for_lrc_file_started_from_the_cover_directory() {
|
||||
let lrc_path = search_for(
|
||||
"tests/samples/Owl City/Cinematic/cover", 1, r".\.lrc");
|
||||
"tests/samples/Owl City/Cinematic/cover",
|
||||
1,
|
||||
®ex::Regex::new(r".\.lrc").unwrap(),
|
||||
);
|
||||
|
||||
assert_matches!(lrc_path, Ok(Some(_)));
|
||||
assert_eq!(
|
||||
|
@ -150,7 +173,10 @@ mod tests {
|
|||
#[test]
|
||||
fn test_search_for_not_exits_file() {
|
||||
let result = search_for(
|
||||
"tests/samples/Owl City/Cinematic/cover", 3, r".\.mp3");
|
||||
"tests/samples/Owl City/Cinematic/cover",
|
||||
3,
|
||||
®ex::Regex::new(r".\.mp3").unwrap(),
|
||||
);
|
||||
|
||||
assert_matches!(result, Ok(None));
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue