Provides typed variants of
Path
and
PathBuf
for Unix
and Windows.
toml
[dependencies]
typed-path = "0.4"
Some applications need to manipulate Windows or UNIX paths on different platforms, for a variety of reasons: constructing portable file formats, parsing files from other platforms, handling archive formats, working with certain network protocols, and so on.
-- Josh Triplett
Check out this issue of a discussion for this. The functionality actually exists within the standard library, but is not exposed!
This means that parsing a path like C:\path\to\file.txt
will be parsed
differently by std::path::Path
depending on which platform you are on!
```rust use std::path::Path;
fn main() {
// On Windows, this prints out:
//
// * Prefix(PrefixComponent { raw: "C:", parsed: Disk(67) })
// * RootDir
// * Normal("path")
// * Normal("to")
// * Normal("file.txt")]
//
// But on Unix, this prints out:
//
// * Normal("C:\path\to\file.txt")
println!(
"{:?}",
Path::new(r"C:\path\to\file.txt")
.components()
.collect::
The library provides a generic Path<T>
and PathBuf<T>
that use [u8]
and
Vec<u8>
underneath instead of OsStr
and OsString
. An encoding generic
type is provided to dictate how the underlying bytes are parsed in order to
support consistent path functionality no matter what operating system you are
compiling against!
```rust use typed_path::WindowsPath;
fn main() {
// On all platforms, this prints out:
//
// * Prefix(PrefixComponent { raw: "C:", parsed: Disk(67) })
// * RootDir
// * Normal("path")
// * Normal("to")
// * Normal("file.txt")]
//
println!(
"{:?}",
WindowsPath::new(r"C:\path\to\file.txt")
.components()
.collect::
Alongside the byte paths, this library also supports UTF8-enforced paths
through UTF8Path<T>
and UTF8PathBuf<T>
, which internally use str
and
String
. An encoding generic type is provided to dictate how the underlying
characters are parsed in order to support consistent path functionality no
matter what operating system you are
compiling against!
```rust use typed_path::Utf8WindowsPath;
fn main() {
// On all platforms, this prints out:
//
// * Prefix(Utf8WindowsPrefixComponent { raw: "C:", parsed: Disk(67) })
// * RootDir
// * Normal("path")
// * Normal("to")
// * Normal("file.txt")]
//
println!(
"{:?}",
Utf8WindowsPath::new(r"C:\path\to\file.txt")
.components()
.collect::
There may be times in which you need to convert between encodings such as when
you want to load a native path and convert it into another format. In that
case, you can use the with_encoding
method to convert a Path
or Utf8Path
into their respective PathBuf
and Utf8PathBuf
with an explicit encoding:
```rust use typed_path::{Utf8Path, Utf8UnixEncoding, Utf8WindowsEncoding};
fn main() {
// Convert from Unix to Windows
let unixpath = Utf8Path::
// Converting from Windows to Unix will drop any prefix
let windows_path = Utf8Path::<Utf8WindowsEncoding>::new(r"C:\tmp\foo.txt");
let unix_path = windows_path.with_encoding::<Utf8UnixEncoding>();
assert_eq!(unix_path, Utf8Path::<Utf8UnixEncoding>::new(r"/tmp/foo.txt"));
// Converting to itself should retain everything
let path = Utf8Path::<Utf8WindowsEncoding>::new(r"C:\tmp\foo.txt");
assert_eq!(
path.with_encoding::<Utf8WindowsEncoding>(),
Utf8Path::<Utf8WindowsEncoding>::new(r"C:\tmp\foo.txt"),
);
} ```
Alongside implementing the standard methods associated with
Path
and
PathBuf
from the
standard library, this crate also implements several additional methods
including the ability to normalize a path by resolving .
and ..
without the
need to have the path exist.
```rust use typed_path::Utf8UnixPath;
assert_eq!( Utf8UnixPath::new("foo/bar//baz/./asdf/quux/..").normalize(), Utf8UnixPath::new("foo/bar/baz/asdf"), ); ```
In addition, you can leverage absolutize
to convert a path to an absolute
form by prepending the current working directory if the path is relative and
then normalizing it:
```rust use typed_path::{utils, Utf8UnixPath};
// With an absolute path, it is just normalized let path = Utf8UnixPath::new("/a/b/../c/./d"); assert_eq!(path.absolutize().unwrap(), Utf8UnixPath::new("/a/c/d"));
// With a relative path, it is first joined with the current working directory // and then normalized let cwd = utils::utf8currentdir().unwrap().withunixencoding(); let path = cwd.join(Utf8UnixPath::new("a/b/../c/./d")); assert_eq!(path.absolutize().unwrap(), cwd.join(Utf8UnixPath::new("a/c/d"))); ```
Helper functions are available in the utils
module, and one of those provides
an identical experience to
std::env::current_dir
:
```rust
// Retrieves the current directory as a NativePath:
//
// * For Unix family, this would be Path
// Retrieves the current directory as a Utf8NativePath:
//
// * For Unix family, this would be Utf8Path
This project is licensed under either of
Apache License, Version 2.0, (LICENSE-APACHE or apache-license) MIT license (LICENSE-MIT or mit-license) at your option.