diff --git a/README.md b/README.md index 53f056a..b1334c0 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ Corresponding methods: | `os.expand_tilde_to_home()` | `Path.expand_tilde()` | | `os.norm_path()` | `Path.normalized()` | | `os.quoted_path()` | `Path.quoted()` | +| n/a | `Path.rel()` | | `os.abs_path()` | `Path.abs()` | | `os.real_path()` | `Path.real()` | | `os.exists()` | `Path.exists()` | diff --git a/pathstr.v b/pathstr.v index ed4e6e3..5d60168 100644 --- a/pathstr.v +++ b/pathstr.v @@ -55,6 +55,40 @@ pub fn (p Path) quoted() string { return os.quoted_path(p) } +// rel returns the relative path to the base path. +pub fn (p Path) rel(base Path) Path { + sep := os.path_separator + + target_parts := p.trim_right(sep).split(sep) + base_parts := base.trim_right(sep).split(sep) + + mut common_idx := 0 + for common_idx < target_parts.len && common_idx < base_parts.len { + if target_parts[common_idx] != base_parts[common_idx] { + break + } + common_idx++ + } + + mut result_parts := []string{} + + up_count := base_parts.len - common_idx + + for _ in 0 .. up_count { + result_parts << '..' + } + + for i := common_idx; i < target_parts.len; i++ { + result_parts << target_parts[i] + } + + if result_parts.len == 0 { + return '.' + } + + return result_parts.join(sep) +} + // abs returns the absolute path. pub fn (p Path) abs() Path { return Path(os.abs_path(p))