use std::{ fs::{self}, io, path::{Path, PathBuf}, }; use walkdir::WalkDir; pub fn path_to_lowercase(path: impl AsRef) -> 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, rel: impl AsRef, ) -> io::Result> { 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(¤t)? { 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, ) -> Result, walkdir::Error> { let a = WalkDir::new(path) .into_iter() .collect::, walkdir::Error>>()? .into_iter() .filter(|entry| entry.file_type().is_file()); Ok(a) } pub fn is_plugin_file(filename: impl AsRef) -> bool { filename .as_ref() .extension() .is_some_and(|ext| ext == "esp" || ext == "esm" || ext == "esl") }