[−][src]Struct ironpath::Absolute
An absolute path that may or may not exist.
This path obeys the following invariants:
- It is absolute, having a prefix (on Windows) and a root directory component.
- It contains only named path components, no
/./
or/../
ones. - It uses the platform-native path-component separator (
/
on POSIX,\
on Windows).
Therefore:
- It's always reasonably straight-forward for humans to understand.
- On Windows, it uses extended-length path syntax, so cross-platform applications don't need to worry about most traditional Windows path limitations.
- You can join more named path components on the end without having to check the filesystem or re-normalize the path.
Since this type implements AsRef<Path>
, it can be used with almost any
standard library function that expects a path.
Examples
use std::fs; use std::io::Write; let log_storage = Absolute::new("/var/log/myapp")?; let current_log = log_storage.join("events")?; let previous_log = log_storage.join("events.old")?; fs::rename(¤t_log, previous_log)?; let mut log_file = fs::OpenOptions::new() .write(true) .create(true) .open(current_log)?; write!(&mut log_file, "Log rotated.")?;
Methods
impl Absolute
[src]
pub fn new<P: AsRef<Path>>(path: P) -> Result<Absolute, Error>
[src]
Convert an arbitrary path to follow the rules for an Absolute
path.
- If the path is relative, it is interpreted relative to the process' current working directory.
- Any
/./
components in the path are removed. - If a component that refers to an existing, readable symlink is
followed by a
/../
component, it will be resolved in the same way as the operating system would (see "Platform-specific behaviour" below). - If a component that does not exist in the filesystem, or which refers
to an ordinary file or directory, is followed by a
/../
component, they cancel each other out and both are removed. - Other components are left alone.
Performance
In the best-case, the given path already follows the rules, and
we only call canonicalize()
on the head (the prefix and root
directory, if any) to convert it to canonical syntax.
If the platform requires it, we will call symlink_metadata()
on
every component preceding a /../
component, and (if it turns out to be
a symlink) read_link()
. The process repeats if the symlink target
includes any /../
components of its own.
Platform-specific behaviour
On Windows, when a path component that refers to a symlink is followed
by /../
, the symlink component is removed, because that's how the
Windows kernel does it.
On Unix, when a path component that refers to a symlink is followed
by /../
, the symlink component is resolved recursively before the /../
is applied, because that's how the Unix kernel does it.
On Windows, this method correctly handles partially-absolute paths like
D:foo\bar.txt
that are relative to a path other than the current
working directory.
On Windows, the resulting path uses extended-length path syntax, so it may confuse other applications not designed to handle such paths. For example, if you pass such a path on another application's command line, or write it to a configuration file.
Errors
Returns Error::IoError
if the head of the given path cannot be
canonicalized. For example, if the process' current working directory
has been deleted, or the given path includes a syntactically invalid
prefix.
The same variant is returned if a problem is encountered while checking if a given path is a symlink, or while trying to read a symlink. For example, if the current user does not have permission to read the directory containing it, or the path is on a network-mounted filesystem that stopped responding.
Returns Error::SymlinkLoops
if resolving a symlink takes us back
to a previously-resolved symlink. For example, if /example/path/a
is a symlink to /example/path/b
, and b
is a symlink back to a
,
then giving this method a path like /example/path/a/../c
will return
this error. It's like the POSIX ELOOP
error, but cross-platform.
Note that "does not exist" is not a fatal error for this function; path components that do not exist by definition are not symlinks, and are treated the same way as every other component that is not a symlink.
Examples
let real_current_directory = Absolute::new(std::env::current_dir()?)?;
pub fn join<P: AsRef<Path>>(&self, path: P) -> Result<Absolute, Error>
[src]
Clone this path, attempting to add an arbitrary relative path on the end.
Performance
An expression like:
absolute_path.join(path)?
...is the same as doing:
absolute_path.join_relative(&Relative::new(path)?)
...and therefore involves the same allocation and other costs as
calling Relative::new()
yourself.
If you plan on joining the same relative path to many Absolute
paths,
it's more efficient to call Relative::new()
once yourself then use
.join_relative()
each time.
Errors
Returns the same errors as Relative::new()
.
Examples
let metadata_path = extraction_path.join("META-INF/MANIFEST.MF")?;
pub fn join_relative(&self, tail: &Relative) -> Absolute
[src]
Clone this path, adding the given Relative
path on the end.
If the thing you want to join isn't already a Relative
, you may find
it more ergonomic to call .join()
instead.
Performance
Since a Relative
is guaranteed to follow the rules for Absolute
paths (except for being absolute), no additional checks or processing
need to be done, just straight concatenation.
Examples
let search_path = vec![ Absolute::new("/usr/local/bin")?, Absolute::new("/bin")?, Absolute::new("/usr/bin")?, Absolute::new("/sbin")?, Absolute::new("/usr/sbin")?, ]; let binary = Relative::new("cargo")?; for prefix in search_path { let guess = prefix.join_relative(&binary); if guess.as_path().is_file() { return Ok(guess) } }
pub fn as_path(&self) -> &Path
[src]
Coerces to a Path
slice.
Since Absolute
implements AsRef<Path>
, this method is not needed
very often—you can often just pass it directly to the thing that needs
a Path
.
Examples
If you really, really need to convert an Absolute
to a PathBuf
:
let owned_path: std::path::PathBuf = absolute_path.as_path().into();
pub fn as_os_str(&self) -> &OsStr
[src]
Coerces to an OsStr
slice.
Since Absolute
implements AsRef<OsStr>
, this method is not needed
very often—you can often just pass it directly to the thing that needs
an OsStr
.
Examples
let install_path = std::env::args_os() .next() .expect("Specify the installation path on the command line."); let windows_path = Absolute::new("C:\\windows").unwrap(); if windows_path.as_os_str() == install_path { panic!("No, you can't install to the Windows path."); }
Trait Implementations
impl PartialOrd<Absolute> for Absolute
[src]
fn partial_cmp(&self, other: &Absolute) -> Option<Ordering>
[src]
fn lt(&self, other: &Absolute) -> bool
[src]
fn le(&self, other: &Absolute) -> bool
[src]
fn gt(&self, other: &Absolute) -> bool
[src]
fn ge(&self, other: &Absolute) -> bool
[src]
impl AsRef<Path> for Absolute
[src]
impl AsRef<OsStr> for Absolute
[src]
impl Ord for Absolute
[src]
fn cmp(&self, other: &Absolute) -> Ordering
[src]
fn max(self, other: Self) -> Self
1.21.0[src]
Compares and returns the maximum of two values. Read more
fn min(self, other: Self) -> Self
1.21.0[src]
Compares and returns the minimum of two values. Read more
fn clamp(self, min: Self, max: Self) -> Self
[src]
clamp
)Restrict a value to a certain interval. Read more
impl Eq for Absolute
[src]
impl Clone for Absolute
[src]
fn clone(&self) -> Absolute
[src]
fn clone_from(&mut self, source: &Self)
1.0.0[src]
Performs copy-assignment from source
. Read more
impl PartialEq<Absolute> for Absolute
[src]
impl Hash for Absolute
[src]
fn hash<__H: Hasher>(&self, state: &mut __H)
[src]
fn hash_slice<H>(data: &[Self], state: &mut H) where
H: Hasher,
1.3.0[src]
H: Hasher,
Feeds a slice of this type into the given [Hasher
]. Read more
impl Debug for Absolute
[src]
Auto Trait Implementations
Blanket Implementations
impl<T, U> Into for T where
U: From<T>,
[src]
U: From<T>,
impl<T> From for T
[src]
impl<T> ToOwned for T where
T: Clone,
[src]
T: Clone,
type Owned = T
The resulting type after obtaining ownership.
fn to_owned(&self) -> T
[src]
fn clone_into(&self, target: &mut T)
[src]
impl<T, U> TryFrom for T where
U: Into<T>,
[src]
U: Into<T>,
type Error = Infallible
The type returned in the event of a conversion error.
fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>
[src]
impl<T> Borrow for T where
T: ?Sized,
[src]
T: ?Sized,
impl<T> BorrowMut for T where
T: ?Sized,
[src]
T: ?Sized,
fn borrow_mut(&mut self) -> &mut T
[src]
impl<T, U> TryInto for T where
U: TryFrom<T>,
[src]
U: TryFrom<T>,
type Error = <U as TryFrom<T>>::Error
The type returned in the event of a conversion error.
fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>
[src]
impl<T> Any for T where
T: 'static + ?Sized,
[src]
T: 'static + ?Sized,