use std::path::{Component, Path, PathBuf};
pub(crate) fn absolute(path: &Path) -> PathBuf {
if path.is_absolute() {
path.to_path_buf()
} else {
std::env::current_dir()
.map(|cwd| cwd.join(path))
.unwrap_or_else(|_| path.to_path_buf())
}
}
pub(crate) fn ancestors_within(start: &Path, root: &Path) -> Vec<PathBuf> {
let root = lexically_normal(&absolute(root));
let start = lexically_normal(&absolute(start));
if !start.starts_with(&root) {
return Vec::new();
}
start
.ancestors()
.take_while(|ancestor| ancestor.starts_with(&root))
.map(Path::to_path_buf)
.collect()
}
pub(crate) fn lexically_normal(path: &Path) -> PathBuf {
let mut normal = PathBuf::new();
for component in path.components() {
match component {
Component::CurDir => {}
Component::ParentDir => {
normal.pop();
}
other => normal.push(other),
}
}
normal
}