use std::fs;
use std::io;
use std::path::{Path, PathBuf};
pub mod path {}
pub fn search_locations<P: AsRef<Path>>(
directories: &[P],
stub: &str,
) -> io::Result<Option<PathBuf>> {
for d in directories {
let p = d.as_ref().join(stub);
if p.try_exists()? {
return Ok(Some(p));
}
}
Ok(None)
}
pub fn search_parents<P: AsRef<Path>>(default_dir: P, stub: &str) -> io::Result<Option<PathBuf>> {
let default_dir = default_dir.as_ref();
let path = default_dir.join(stub);
if path.try_exists()? {
Ok(Some(path))
} else if let Some(p) = default_dir.parent() {
search_parents(p, stub)
} else {
Ok(None)
}
}
pub fn search_recursive<P: AsRef<Path>>(default_dir: P, stub: &str) -> io::Result<Option<PathBuf>> {
let default_dir = default_dir.as_ref();
let attempt = default_dir.join(stub);
if attempt.try_exists()? {
return Ok(Some(attempt));
}
let dir = fs::read_dir(default_dir)?
.filter_map(|e| e.ok())
.filter_map(|e| {
if e.metadata().ok()?.is_dir() {
Some(e)
} else {
None
}
});
for entry in dir {
if let Ok(Some(p)) = search_recursive(entry.path(), stub) {
return Ok(Some(p));
}
}
Ok(None)
}