|
|
|
@ -1,6 +1,6 @@
|
|
|
|
|
use std::ffi::OsStr;
|
|
|
|
|
|
|
|
|
|
use crate::path::PathBuf;
|
|
|
|
|
use crate::path::{Components, PathBuf};
|
|
|
|
|
use crate::{fs, io};
|
|
|
|
|
|
|
|
|
|
/// This struct is an async version of [`std::path::Path`].
|
|
|
|
@ -28,7 +28,7 @@ impl Path {
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```no_run
|
|
|
|
|
/// use crate::path::{Path, PathBuf};
|
|
|
|
|
/// use async_std::path::{Path, PathBuf};
|
|
|
|
|
///
|
|
|
|
|
/// let path = Path::new("/foo/test/../test/bar.rs");
|
|
|
|
|
/// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
|
|
|
|
@ -37,6 +37,45 @@ impl Path {
|
|
|
|
|
fs::canonicalize(self).await
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Produces an iterator over the [`Component`]s of the path.
|
|
|
|
|
///
|
|
|
|
|
/// When parsing the path, there is a small amount of normalization:
|
|
|
|
|
///
|
|
|
|
|
/// * Repeated separators are ignored, so `a/b` and `a//b` both have
|
|
|
|
|
/// `a` and `b` as components.
|
|
|
|
|
///
|
|
|
|
|
/// * Occurrences of `.` are normalized away, except if they are at the
|
|
|
|
|
/// beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
|
|
|
|
|
/// `a/b` all have `a` and `b` as components, but `./a/b` starts with
|
|
|
|
|
/// an additional [`CurDir`] component.
|
|
|
|
|
///
|
|
|
|
|
/// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
|
|
|
|
|
///
|
|
|
|
|
/// Note that no other normalization takes place; in particular, `a/c`
|
|
|
|
|
/// and `a/b/../c` are distinct, to account for the possibility that `b`
|
|
|
|
|
/// is a symbolic link (so its parent isn't `a`).
|
|
|
|
|
///
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use async_std::path::{Path, Component};
|
|
|
|
|
/// use std::ffi::OsStr;
|
|
|
|
|
///
|
|
|
|
|
/// let mut components = Path::new("/tmp/foo.txt").components();
|
|
|
|
|
///
|
|
|
|
|
/// assert_eq!(components.next(), Some(Component::RootDir));
|
|
|
|
|
/// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("tmp"))));
|
|
|
|
|
/// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("foo.txt"))));
|
|
|
|
|
/// assert_eq!(components.next(), None)
|
|
|
|
|
/// ```
|
|
|
|
|
///
|
|
|
|
|
/// [`Component`]: enum.Component.html
|
|
|
|
|
/// [`CurDir`]: enum.Component.html#variant.CurDir
|
|
|
|
|
pub fn components(&self) -> Components<'_> {
|
|
|
|
|
let path: &std::path::Path = self.into();
|
|
|
|
|
path.components()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/// Directly wraps a string slice as a `Path` slice.
|
|
|
|
|
///
|
|
|
|
|
/// This is a cost-free conversion.
|
|
|
|
@ -44,7 +83,7 @@ impl Path {
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use crate::path::Path;
|
|
|
|
|
/// use async_std::path::Path;
|
|
|
|
|
///
|
|
|
|
|
/// Path::new("foo.txt");
|
|
|
|
|
/// ```
|
|
|
|
@ -52,7 +91,7 @@ impl Path {
|
|
|
|
|
/// You can create `Path`s from `String`s, or even other `Path`s:
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use crate::path::Path;
|
|
|
|
|
/// use async_std::path::Path;
|
|
|
|
|
///
|
|
|
|
|
/// let string = String::from("foo.txt");
|
|
|
|
|
/// let from_string = Path::new(&string);
|
|
|
|
@ -70,7 +109,7 @@ impl Path {
|
|
|
|
|
/// # Examples
|
|
|
|
|
///
|
|
|
|
|
/// ```
|
|
|
|
|
/// use crate::path::{Path, PathBuf};
|
|
|
|
|
/// use async_std::path::{Path, PathBuf};
|
|
|
|
|
///
|
|
|
|
|
/// let path_buf = Path::new("foo.txt").to_path_buf();
|
|
|
|
|
/// assert_eq!(path_buf, PathBuf::from("foo.txt"));
|
|
|
|
@ -98,8 +137,40 @@ impl AsRef<Path> for Path {
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsRef<Path> for OsStr {
|
|
|
|
|
fn as_ref(&self) -> &Path {
|
|
|
|
|
Path::new(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl AsRef<Path> for str {
|
|
|
|
|
fn as_ref(&self) -> &Path {
|
|
|
|
|
Path::new(self)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::fmt::Debug for Path {
|
|
|
|
|
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
|
|
std::fmt::Debug::fmt(&self.inner, formatter)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::cmp::PartialEq for Path {
|
|
|
|
|
fn eq(&self, other: &Path) -> bool {
|
|
|
|
|
self.components().eq(other.components())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::cmp::Eq for Path {}
|
|
|
|
|
|
|
|
|
|
impl std::cmp::PartialOrd for Path {
|
|
|
|
|
fn partial_cmp(&self, other: &Path) -> Option<std::cmp::Ordering> {
|
|
|
|
|
self.components().partial_cmp(other.components())
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl std::cmp::Ord for Path {
|
|
|
|
|
fn cmp(&self, other: &Path) -> std::cmp::Ordering {
|
|
|
|
|
self.components().cmp(other.components())
|
|
|
|
|
}
|
|
|
|
|
}
|