summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs49
1 files changed, 38 insertions, 11 deletions
diff --git a/src/lib.rs b/src/lib.rs
index fa6b1a9..9e9afcf 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,15 +1,11 @@
-use std::path::{Path, PathBuf, Component};
+use std::path::{Component, Path, PathBuf};
#[derive(Debug)]
pub enum NormalizeError {
EmptyInput,
}
-pub fn normalize_path(
- _root: &Path,
- origin: &Path,
- input: &Path,
-) -> Result<PathBuf, NormalizeError> {
+pub fn normalize_path(root: &Path, origin: &Path, input: &Path) -> Result<PathBuf, NormalizeError> {
if input.as_os_str().is_empty() {
return Err(NormalizeError::EmptyInput);
}
@@ -18,13 +14,26 @@ pub fn normalize_path(
for component in origin_joint_input.components() {
match component {
Component::CurDir => (),
- Component::ParentDir => { stack.pop(); },
- Component::Prefix(_) => { stack.push(component); },
- Component::Normal(_) => { stack.push(component); },
- Component::RootDir => { stack.push(component) },
+ Component::ParentDir => {
+ stack.pop();
+ }
+ Component::Prefix(_) => stack.push(component),
+ Component::Normal(_) => stack.push(component),
+ Component::RootDir => stack.push(component),
}
}
- Ok(PathBuf::from_iter(stack))
+ let normalized_origin_join_input = PathBuf::from_iter(stack);
+ Ok(normalize_to_root(&normalized_origin_join_input, root))
+}
+
+fn normalize_to_root(target_path: &Path, root: &Path,) -> PathBuf {
+ match target_path.strip_prefix(root) {
+ Ok(normalized_path) => normalized_path.to_path_buf(),
+ Err(_) => {
+ let root_parent = root.parent().expect("failed cuz target_path is not absolute");
+ PathBuf::from("..").join(normalize_to_root(target_path, root_parent))
+ },
+ }
}
#[cfg(test)]
@@ -61,4 +70,22 @@ mod tests {
assert!(result.is_ok());
assert_eq!(result.unwrap(), Path::new("main.rs"));
}
+
+ #[test]
+ fn path_is_made_relative_to_root() {
+ let root = Path::new("/project");
+ let origin_dir = Path::new("/project/src");
+ let input = Path::new("main.rs");
+ let result = normalize_path(root, origin_dir, input);
+ assert_eq!(result.unwrap(), Path::new("src/main.rs"));
+ }
+
+ #[test]
+ fn path_is_made_relative_to_root_from_outside() {
+ let root = Path::new("/project");
+ let origin_dir = Path::new("/outside");
+ let input = Path::new("main.rs");
+ let result = normalize_path(root, origin_dir, input);
+ assert_eq!(result.unwrap(), Path::new("../outside/main.rs"));
+ }
}