The file_paths
crate provides relativity and resolution for textual file paths. Path
is based on a variant for compliance reasons. The provided Path
isn't specifically a "file path", it does no system operation.
It's supports two variants (PlatformPathVariant
):
Common
: considers absolute paths as starting with a path separator onlyWindows
: considers absolute paths as either:- starting with a UNC prefix (
\\
); - starting with a drive prefix (
drive:
); - starting with a path separator.
- starting with a UNC prefix (
It might not be useful in pratice to have these variants: wouldn't it simply be easier to always use Windows
? This Path
is based on Common
, so I'd like to keep them separate for compliance (for example, someone might want the is_absolute
method to work a certain way for a certain purpose, and Path
isn't necessarily a file operation or a file operation in the operating system).
PlatformPathVariant::NATIVE
yields the target platform proper one.
Path
can be constructed with _native
and _common
suffixes too.
#[test]
fn relativity() {
assert_eq!("", Path::new_common("/a/b").relative("/a/b"));
assert_eq!("c", Path::new_common("/a/b").relative("/a/b/c"));
assert_eq!("../../c/d", Path::new_common("/a/b/c").relative("/a/c/d"));
assert_eq!("..", Path::new_common("/a/b/c").relative("/a/b"));
assert_eq!("../..", Path::new_common("/a/b/c").relative("/a"));
assert_eq!("..", Path::new_common("/a").relative("/"));
assert_eq!("a", Path::new_common("/").relative("/a"));
assert_eq!("", Path::new_common("/").relative("/"));
assert_eq!("../../c/d", Path::new_common("/a/b").relative("/c/d"));
assert_eq!("../c", Path::new_common("/a/b").relative("/a/c"));
let windows = PlatformPathVariant::Windows;
assert_eq!("", Path::new("C:/", windows).relative("C:/"));
assert_eq!("", Path::new("C:/foo", windows).relative("C:/foo"));
assert_eq!(r"\\foo", Path::new("C:/", windows).relative(r"\\foo"));
assert_eq!("../../foo", Path::new(r"\\a/b", windows).relative(r"\\foo"));
assert_eq!("D:/", Path::new("C:/", windows).relative(r"D:"));
}
#[test]
fn resolution() {
assert_eq!("a", Path::from_n_common(["a/b/.."]).to_string());
assert_eq!("a", Path::from_n_common(["a", "b", ".."]).to_string());
assert_eq!("/a/b", Path::new_common("/c").resolve("/a/b").to_string());
assert_eq!("a", Path::new_common("a/b").resolve("..").to_string());
assert_eq!("a/b", Path::new_common("a/b/").to_string());
assert_eq!("a/b", Path::new_common("a//b").to_string());
let windows = PlatformPathVariant::Windows;
assert_eq!(r"\\Whack/a/Box", Path::from_n(["foo", r"\\Whack////a//Box", "..", "Box"], windows).to_string());
assert_eq!("C:/a", Path::new("C:/", windows).resolve("a").to_string());
assert_eq!("D:/", Path::new("C:/", windows).resolve("D:/").to_string());
assert_eq!("D:/a", Path::new("D:/a", windows).to_string());
assert_eq!("C:/a/f/b", Path::new("a", windows).resolve("C:/a///f//b").to_string());
}
Can anyone tell me if there's a name better than file_paths
since it's not limited to files? (I'm thinking of using this both in file system and node paths)