Expand description
Cross-platform intelligent path creation, resolution, and manipulation.
§Path Normalization
Path slashes are normalized to your platform’s native path format at creation and modification. This resolves PathBuf’s issue of returning to you the exact string you passed to it, even if it’s incorrect for the current platform.
#[cfg(unix)]
{
// Standard Library
use std::path::PathBuf;
let mut path_buf = PathBuf::from("\\foo\\bar\\baz.txt");
assert_eq!(path_buf.to_string_lossy(),"\\foo\\bar\\baz.txt");
// OsPath
use os_path::OsPath;
let mut os_path = OsPath::from("\\foo\\bar\\baz.txt");
assert_eq!(os_path.to_string(),"/foo/bar/baz.txt");
}
§False Root Handling
#[cfg(unix)]
{
// Standard Library
use std::path::PathBuf;
let mut path_buf = PathBuf::new();
path_buf.push("/foo/bar");
path_buf.push("/baz/pow.txt");
assert_eq!(path_buf.to_string_lossy(),"/baz/pow.txt");
// OsPath
use os_path::OsPath;
let mut os_path = OsPath::new();
os_path.push("/foo/bar");
os_path.push("/baz.txt");
assert_eq!(os_path.to_string(),"/foo/bar/baz.txt");
}
False root errors occur when you you attempt to join paths with leading slashes. In the above example we have
/foo/bar
and we push() /baz.txt
to it. With the standard libraries Path and PathBuf, you’ll end up with /baz.txt
as your path. This is very counter intuitive, and requires extra code be written to strip the leading slash in order
to prevent this.
Instead, OsPath will do what you expect, and return /foo/bar/baz.txt
.
And OsPath does this while still assuming at the start that both paths were absolute. If you queried either path
beforehand, they would both return true for is_absolute()
. However, when you joined the two paths, OsPath correctly
assumes the second path is relative to the first, and joins them correctly.
Note that this is not a problem on Windows, as attempting to join any path starting with
C:\
is nonsensical, while joinging a path prefixed with/
or\\
is not.
§Path Resolution and Traversal
If you join()
or push()
a path that starts with ..
, OsPath will traverse the path, and build the correct path.
#[cfg(unix)]
{
// Standard Library
use std::path::PathBuf;
let mut path_buf = PathBuf::new();
path_buf.push("/foo/bar");
path_buf.push("../baz.txt");
assert_eq!(path_buf.to_string_lossy(),"/foo/bar/../baz.txt");
// OsPath
use os_path::OsPath;
let mut os_path = OsPath::new();
os_path.push("/foo/bar/");
os_path.push("../baz.txt");
assert_eq!(os_path.to_string(),"/foo/baz.txt");
}
OsPath can handle multiple ..
in a row, and will traverse the path correctly.
#[cfg(unix)]
{
use os_path::OsPath;
let mut os_path = OsPath::new();
os_path.push("/foo/bar/baz/");
os_path.push("../../pow.txt");
assert_eq!(os_path.to_string(),"/foo/pow.txt");
}
And, if your path ends in a file, and you join()
or push()
a path that starts with ..
, OsPath will traverse the
path, and build the correct path, skipping over the file.
#[cfg(unix)]
{
use os_path::OsPath;
let mut os_path = OsPath::new();
os_path.push("/foo/bar/baz.txt");
os_path.push("../pow.txt");
assert_eq!(os_path.to_string(),"/foo/pow.txt");
}
§File And Directory Handling
If the path ends in a /
or \\
OsPath assumes this is a directory, otherwise it’s a file.
Structs§
- An intelligent path type that can be used in place of
std::path::PathBuf
.