[][src]Struct ironpath::Absolute

pub struct 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(&current_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 Eq for Absolute[src]

impl PartialOrd<Absolute> for Absolute[src]

impl PartialEq<Absolute> for Absolute[src]

impl AsRef<Path> for Absolute[src]

impl AsRef<OsStr> for Absolute[src]

impl Clone for Absolute[src]

fn clone_from(&mut self, source: &Self)
1.0.0
[src]

Performs copy-assignment from source. Read more

impl Ord for Absolute[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]

🔬 This is a nightly-only experimental API. (clamp)

Restrict a value to a certain interval. Read more

impl Debug for Absolute[src]

impl Hash for Absolute[src]

fn hash_slice<H>(data: &[Self], state: &mut H) where
    H: Hasher
1.3.0
[src]

Feeds a slice of this type into the given [Hasher]. Read more

Auto Trait Implementations

impl Send for Absolute

impl Sync for Absolute

Blanket Implementations

impl<T, U> Into for T where
    U: From<T>, 
[src]

impl<T> ToOwned for T where
    T: Clone
[src]

type Owned = T

The resulting type after obtaining ownership.

impl<T> From for T[src]

impl<T, U> TryFrom for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T> Borrow for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]

impl<T> BorrowMut for T where
    T: ?Sized
[src]

impl<T, U> TryInto for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.