use std::path::{Component, Path, PathBuf};
pub(crate) fn path_lookup_candidates(file_path: &str) -> Vec<String> {
let path = Path::new(file_path);
let mut candidates = Vec::new();
candidates.push(file_path.replace('\\', "/"));
candidates.push(normalize_path_to_slash(path));
if let Ok(stripped) = path.strip_prefix(".") {
candidates.push(normalize_path_to_slash(stripped));
}
candidates.sort();
candidates.dedup();
candidates
}
pub(crate) fn normalize_path_to_slash(path: &Path) -> String {
let mut normalized = PathBuf::new();
for component in path.components() {
match component {
Component::CurDir => {}
Component::ParentDir => {
normalized.pop();
}
Component::Normal(part) => normalized.push(part),
Component::RootDir | Component::Prefix(_) => {}
}
}
normalized.to_string_lossy().replace('\\', "/")
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn path_candidates_accept_plain_and_leading_dot_paths() {
assert_eq!(
path_lookup_candidates("./src/main.rs"),
vec!["./src/main.rs".to_string(), "src/main.rs".to_string()]
);
}
#[test]
fn normalized_path_collapses_current_and_parent_components() {
assert_eq!(
normalize_path_to_slash(Path::new("./src/bin/../main.rs")),
"src/main.rs"
);
}
}