(Alternatively rendered RFC document here)
As part of feedback gathered by the CLI-WG we have concluded that there are several key aspects of path management missing from the Rust stdlib. Most of this pre-RFC is based on the summary made by this comment.
The addition of these functions will have a positive impact on the Rust ecosystem as a whole. It will enable users to write CLI applications more quickly, without having to re-invent the wheel. Additionally these functions fit neatly into already existing structures and modules.
Additions to the
stdlib are made to the
fs module, the
fs::normalize function is added that operates simmilarly to
fs::canonicalize. The difference is that it doesn’t actually touch the filesystem. This means that it wouldn’t fail to normalize a path if a directory does not exist.
PathBuf will gain a new, non-destructive
append function which will operate similarly to the already existing
push. However it will never overwrite the buffer, even if the provided path segment is absolute.
let mut path = PathBuf::from("/usr"); // --> /usr path.append("/lib"); // --> /usr/lib path.push("/etc"); // --> /etc
Path will gain a new function
concat which operates simmilarly as
PathBuf::append. It always appends provided path segments, even if they were absolute (see
Path::new("/usr").concat("/lib"); // --> /usr/lib Path::new("/usr").join("/lib"); // --> /lib
Path would also gain two more functions for computing relative paths to a base one, as well as the absolute base path for any given relative one. These functions require the current working directory (CWD) to be available. Although in cases where
Path::starts_with is true,
relative_to would not require it.
fs::normalize provides the same functional output as
fs::canonicalize, it’s implementation is quite different, as it can not rely on either
realpath (for unix) or
CreateFile (Windows) to do it’s job.
This means that file path canonicalization needs to be done on it’s own, or using some other backend implementation.
Path functions work similarly in their design that a lot of the code can be shared from
Path::join respectively, while those functions can become wrappers around
Path::concat with different input sanitisation/ handling.
Path::absolute the most leg-work is required. Because in cases where
Path::starts_with for the base-path of
Path::relative_to is false, the CWD is required to compute the path difference, there should be a generalized way of getting the current working directory.
Optionally another function could be added to the
fs module, that exposes this, however this is entirely optional.
Path::absolute require additional utilities to be available in the
fs module and could add unwanted complexity to it. In case this is a problem, these two functions can be excluded, with a crate potentially implementing them, without having any impact on the other additions made.
For the other functions no drawbacks exist that we are aware of at this time.
Rationale and alternatives
While all of these functions could be provided via external crates, we believe that the inclusion into
Path respectively will yield the best developer experience in the long run, providing common ground between different applications and libraries, that want to use these functions, alike.
Overall the inclusion of these functions in the
stdlib to have a positive effect on the Rust ecosystem.