This repository was archived by the owner on Sep 2, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathpath.rs
More file actions
98 lines (94 loc) · 3.62 KB
/
Copy pathpath.rs
File metadata and controls
98 lines (94 loc) · 3.62 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
//! Utilities for path manipulation.
use alloc::string::String;
/// Returns the canonical form of the path with all intermediate components
/// normalized.
///
/// It won't force convert the path to an absolute form.
///
/// # Examples
///
/// ```
/// use axfs_vfs::path::canonicalize;
///
/// assert_eq!(canonicalize("/path/./to//foo"), "/path/to/foo");
/// assert_eq!(canonicalize("/./path/to/../bar.rs"), "/path/bar.rs");
/// assert_eq!(canonicalize("./foo/./bar"), "foo/bar");
/// ```
pub fn canonicalize(path: &str) -> String {
let mut buf = String::new();
let is_absolute = path.starts_with('/');
for part in path.split('/') {
match part {
"" | "." => continue,
".." => {
while !buf.is_empty() {
if buf == "/" {
break;
}
let c = buf.pop().unwrap();
if c == '/' {
break;
}
}
}
_ => {
if buf.is_empty() {
if is_absolute {
buf.push('/');
}
} else if !&buf.ends_with('/') {
buf.push('/');
}
buf.push_str(part);
}
}
}
if is_absolute && buf.is_empty() {
buf.push('/');
}
buf
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_path_canonicalize() {
assert_eq!(canonicalize(""), "");
assert_eq!(canonicalize("///"), "/");
assert_eq!(canonicalize("//a//.//b///c//"), "/a/b/c");
assert_eq!(canonicalize("/a/../"), "/");
assert_eq!(canonicalize("/a/../..///"), "/");
assert_eq!(canonicalize("a/../"), "");
assert_eq!(canonicalize("a/..//.."), "");
assert_eq!(canonicalize("././a"), "a");
assert_eq!(canonicalize(".././a"), "a");
assert_eq!(canonicalize("/././a"), "/a");
assert_eq!(canonicalize("/abc/../abc"), "/abc");
assert_eq!(canonicalize("/test"), "/test");
assert_eq!(canonicalize("/test/"), "/test");
assert_eq!(canonicalize("test/"), "test");
assert_eq!(canonicalize("test"), "test");
assert_eq!(canonicalize("/test//"), "/test");
assert_eq!(canonicalize("/test/foo"), "/test/foo");
assert_eq!(canonicalize("/test/foo/"), "/test/foo");
assert_eq!(canonicalize("/test/foo/bar"), "/test/foo/bar");
assert_eq!(canonicalize("/test/foo/bar//"), "/test/foo/bar");
assert_eq!(canonicalize("/test//foo/bar//"), "/test/foo/bar");
assert_eq!(canonicalize("/test//./foo/bar//"), "/test/foo/bar");
assert_eq!(canonicalize("/test//./.foo/bar//"), "/test/.foo/bar");
assert_eq!(canonicalize("/test//./..foo/bar//"), "/test/..foo/bar");
assert_eq!(canonicalize("/test//./../foo/bar//"), "/foo/bar");
assert_eq!(canonicalize("/test/../foo"), "/foo");
assert_eq!(canonicalize("/test/bar/../foo"), "/test/foo");
assert_eq!(canonicalize("../foo"), "foo");
assert_eq!(canonicalize("../foo/"), "foo");
assert_eq!(canonicalize("/../foo"), "/foo");
assert_eq!(canonicalize("/../foo/"), "/foo");
assert_eq!(canonicalize("/../../foo"), "/foo");
assert_eq!(canonicalize("/bleh/../../foo"), "/foo");
assert_eq!(canonicalize("/bleh/bar/../../foo"), "/foo");
assert_eq!(canonicalize("/bleh/bar/../../foo/.."), "/");
assert_eq!(canonicalize("/bleh/bar/../../foo/../meh"), "/meh");
assert_eq!(canonicalize("/@test_7_tmpæ/_parent_foo/"), "/@test_7_tmpæ/_parent_foo");
}
}