diff options
Diffstat (limited to 'library/std/src/path.rs')
| -rw-r--r-- | library/std/src/path.rs | 78 |
1 files changed, 77 insertions, 1 deletions
diff --git a/library/std/src/path.rs b/library/std/src/path.rs index 85cad65da6a..dc5922c53ba 100644 --- a/library/std/src/path.rs +++ b/library/std/src/path.rs @@ -85,7 +85,7 @@ use crate::str::FromStr; use crate::sync::Arc; use crate::ffi::{OsStr, OsString}; - +use crate::sys; use crate::sys::path::{is_sep_byte, is_verbatim_sep, parse_prefix, MAIN_SEP_STR}; //////////////////////////////////////////////////////////////////////////////// @@ -3164,3 +3164,79 @@ impl Error for StripPrefixError { "prefix not found" } } + +/// Makes the path absolute without accessing the filesystem. +/// +/// If the path is relative, the current directory is used as the base directory. +/// All intermediate components will be resolved according to platforms-specific +/// rules but unlike [`canonicalize`][crate::fs::canonicalize] this does not +/// resolve symlinks and may succeed even if the path does not exist. +/// +/// If the `path` is empty or getting the +/// [current directory][crate::env::current_dir] fails then an error will be +/// returned. +/// +/// # Examples +/// +/// ## Posix paths +/// +/// ``` +/// #![feature(absolute_path)] +/// # #[cfg(unix)] +/// fn main() -> std::io::Result<()> { +/// use std::path::{self, Path}; +/// +/// // Relative to absolute +/// let absolute = path::absolute("foo/./bar")?; +/// assert!(absolute.ends_with("foo/bar")); +/// +/// // Absolute to absolute +/// let absolute = path::absolute("/foo//test/.././bar.rs")?; +/// assert_eq!(absolute, Path::new("/foo/test/../bar.rs")); +/// Ok(()) +/// } +/// # #[cfg(not(unix))] +/// # fn main() {} +/// ``` +/// +/// The paths is resolved using [POSIX semantics][posix-semantics] except that +/// it stops short of resolving symlinks. This means it will keep `..` +/// components and trailing slashes. +/// +/// ## Windows paths +/// +/// ``` +/// #![feature(absolute_path)] +/// # #[cfg(windows)] +/// fn main() -> std::io::Result<()> { +/// use std::path::{self, Path}; +/// +/// // Relative to absolute +/// let absolute = path::absolute("foo/./bar")?; +/// assert!(absolute.ends_with(r"foo\bar")); +/// +/// // Absolute to absolute +/// let absolute = path::absolute(r"C:\foo//test\..\./bar.rs")?; +/// +/// assert_eq!(absolute, Path::new(r"C:\foo\bar.rs")); +/// Ok(()) +/// } +/// # #[cfg(not(windows))] +/// # fn main() {} +/// ``` +/// +/// For verbatim paths this will simply return the path as given. For other +/// paths this is currently equivalent to calling [`GetFullPathNameW`][windows-path] +/// This may change in the future. +/// +/// [posix-semantics]: https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13 +/// [windows-path]: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getfullpathnamew +#[unstable(feature = "absolute_path", issue = "none")] +pub fn absolute<P: AsRef<Path>>(path: P) -> io::Result<PathBuf> { + let path = path.as_ref(); + if path.as_os_str().is_empty() { + Err(io::const_io_error!(io::ErrorKind::InvalidInput, "cannot make an empty path absolute",)) + } else { + sys::path::absolute(path) + } +} |
