diff options
| -rw-r--r-- | src/lib.rs | 35 |
1 files changed, 28 insertions, 7 deletions
@@ -1,4 +1,4 @@ -use std::path::{Path, PathBuf}; +use std::path::{Path, PathBuf, Component}; #[derive(Debug)] pub enum NormalizeError { @@ -7,13 +7,24 @@ pub enum NormalizeError { pub fn normalize_path( _root: &Path, - _origin: &Path, + origin: &Path, input: &Path, ) -> Result<PathBuf, NormalizeError> { if input.as_os_str().is_empty() { return Err(NormalizeError::EmptyInput); } - Ok(input.to_path_buf()) + let mut stack = Vec::new(); + let origin_joint_input = origin.join(input); + 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) }, + } + } + Ok(PathBuf::from_iter(stack)) } #[cfg(test)] @@ -24,8 +35,8 @@ mod tests { #[test] fn empty_path_returns_error() { - let root = Path::new("/project"); - let origin_dir = Path::new("/project"); + let root = Path::new(""); + let origin_dir = Path::new(""); let input = Path::new(""); let result = normalize_path(root, origin_dir, input); assert!(matches!(result, Err(NormalizeError::EmptyInput))); @@ -33,11 +44,21 @@ mod tests { #[test] fn plain_filename_with_root_at_cwd_returns_filename() { - let root = Path::new("/project"); - let origin_dir = Path::new("/project"); + let root = Path::new(""); + let origin_dir = Path::new(""); let input = Path::new("main.rs"); let result = normalize_path(root, origin_dir, input); assert!(result.is_ok()); assert_eq!(result.unwrap(), Path::new("main.rs")); } + + #[test] + fn relative_path_from_origin_is_resolved() { + let root = Path::new(""); + let origin_dir = Path::new("src"); + let input = Path::new("../main.rs"); + let result = normalize_path(root, origin_dir, input); + assert!(result.is_ok()); + assert_eq!(result.unwrap(), Path::new("main.rs")); + } } |
