Files
fomod-manager/src/utils.rs
2026-03-20 13:10:29 +01:00

67 lines
1.6 KiB
Rust

use std::{
fs::{self},
io,
path::{Path, PathBuf},
};
use walkdir::WalkDir;
pub fn path_to_lowercase(path: impl AsRef<Path>) -> PathBuf {
PathBuf::from(path.as_ref().to_string_lossy().to_lowercase())
}
/// Searches for a path but ignores case. Returns the first it finds.
pub fn resolve_case_insensitive(
base: impl AsRef<Path>,
rel: impl AsRef<Path>,
) -> io::Result<Option<PathBuf>> {
let mut current = base.as_ref().to_path_buf();
for part in rel.as_ref().iter() {
let target = part.to_string_lossy();
let mut found = None;
for entry in fs::read_dir(&current)? {
let entry = entry?;
let name = entry.file_name();
let name = name.to_string_lossy();
if name.eq_ignore_ascii_case(&target) {
found = Some(entry.path());
break;
}
}
match found {
Some(path) => current = path,
None => {
return Ok(None);
}
}
}
Ok(Some(current))
}
/// Use walkdir to walk all actual files in a dir
/// Returns early if any error occurs
pub fn walk_all_files(
path: impl AsRef<Path>,
) -> Result<impl Iterator<Item = walkdir::DirEntry>, walkdir::Error> {
let a = WalkDir::new(path)
.into_iter()
.collect::<Result<Vec<_>, walkdir::Error>>()?
.into_iter()
.filter(|entry| entry.file_type().is_file());
Ok(a)
}
pub fn is_plugin_file(filename: impl AsRef<Path>) -> bool {
filename
.as_ref()
.extension()
.is_some_and(|ext| ext == "esp" || ext == "esm" || ext == "esl")
}