use std::path::PathBuf; pub enum DirSearchPattern<'a> { File(&'a str), Dir(&'a str), } /// Searches upward from the given path towards parent directories. /// If any ancestor directory contains a file or directory matching the pattern, /// returns that ancestor directory's path. pub fn dir_search_prev(path: impl Into, pattern: DirSearchPattern) -> Option { let mut current: PathBuf = path.into(); // Canonicalize the path if possible to ensure absolute traversal if let Ok(canonical) = current.canonicalize() { current = canonical; } else { // If canonicalization fails (e.g. path does not exist yet), // try to make it absolute using current dir if current.is_relative() && let Ok(cwd) = std::env::current_dir() { current = cwd.join(¤t); } } loop { // Check if the current directory exists and is a directory if current.is_dir() { let has_match = match &pattern { DirSearchPattern::File(name) => { let mut entry = current.clone(); entry.push(name); entry.is_file() } DirSearchPattern::Dir(name) => { let mut entry = current.clone(); entry.push(name); entry.is_dir() } }; if has_match { return Some(current); } } // Try to go to the parent directory if !current.pop() { // pop() returns false when there's no parent break; } } None }