use std::path::{Path, PathBuf, Component}; pub fn to_repo_relative(path: &PathBuf, root: &PathBuf) -> PathBuf { path.strip_prefix(root).unwrap().to_path_buf() } pub fn to_string(path: &PathBuf) -> String { path.to_str().unwrap().to_string() } /// Improve the path to try remove and solve .. token. /// Taken from https://stackoverflow.com/questions/68231306/stdfscanonicalize-for-files-that-dont-exist /// /// This assumes that `a/b/../c` is `a/c` which might be different from /// what the OS would have chosen when b is a link. This is OK /// for broot verb arguments but can't be generally used elsewhere /// /// This function ensures a given path ending with '/' still /// ends with '/' after normalization. pub fn normalize_path>(path: P) -> PathBuf { let ends_with_slash = path.as_ref() .to_str() .map_or(false, |s| s.ends_with('/')); let mut normalized = PathBuf::new(); for component in path.as_ref().components() { match &component { Component::ParentDir => { if !normalized.pop() { normalized.push(component); } } _ => { normalized.push(component); } } } if ends_with_slash { normalized.push(""); } normalized }