Skip to content

Commit 3bd6a9d

Browse files
committed
Implemented components
1 parent e27b578 commit 3bd6a9d

File tree

2 files changed

+84
-5
lines changed

2 files changed

+84
-5
lines changed

src/path/path.rs

Lines changed: 76 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use std::ffi::OsStr;
22

3-
use crate::path::PathBuf;
3+
use crate::path::{Components, PathBuf};
44
use crate::{fs, io};
55

66
/// This struct is an async version of [`std::path::Path`].
@@ -28,7 +28,7 @@ impl Path {
2828
/// # Examples
2929
///
3030
/// ```no_run
31-
/// use crate::path::{Path, PathBuf};
31+
/// use async_std::path::{Path, PathBuf};
3232
///
3333
/// let path = Path::new("/foo/test/../test/bar.rs");
3434
/// assert_eq!(path.canonicalize().unwrap(), PathBuf::from("/foo/test/bar.rs"));
@@ -37,22 +37,61 @@ impl Path {
3737
fs::canonicalize(self).await
3838
}
3939

40+
/// Produces an iterator over the [`Component`]s of the path.
41+
///
42+
/// When parsing the path, there is a small amount of normalization:
43+
///
44+
/// * Repeated separators are ignored, so `a/b` and `a//b` both have
45+
/// `a` and `b` as components.
46+
///
47+
/// * Occurrences of `.` are normalized away, except if they are at the
48+
/// beginning of the path. For example, `a/./b`, `a/b/`, `a/b/.` and
49+
/// `a/b` all have `a` and `b` as components, but `./a/b` starts with
50+
/// an additional [`CurDir`] component.
51+
///
52+
/// * A trailing slash is normalized away, `/a/b` and `/a/b/` are equivalent.
53+
///
54+
/// Note that no other normalization takes place; in particular, `a/c`
55+
/// and `a/b/../c` are distinct, to account for the possibility that `b`
56+
/// is a symbolic link (so its parent isn't `a`).
57+
///
58+
/// # Examples
59+
///
60+
/// ```
61+
/// use async_std::path::{Path, Component};
62+
/// use std::ffi::OsStr;
63+
///
64+
/// let mut components = Path::new("/tmp/foo.txt").components();
65+
///
66+
/// assert_eq!(components.next(), Some(Component::RootDir));
67+
/// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("tmp"))));
68+
/// assert_eq!(components.next(), Some(Component::Normal(OsStr::new("foo.txt"))));
69+
/// assert_eq!(components.next(), None)
70+
/// ```
71+
///
72+
/// [`Component`]: enum.Component.html
73+
/// [`CurDir`]: enum.Component.html#variant.CurDir
74+
pub fn components(&self) -> Components<'_> {
75+
let path: &std::path::Path = self.into();
76+
path.components()
77+
}
78+
4079
/// Directly wraps a string slice as a `Path` slice.
4180
///
4281
/// This is a cost-free conversion.
4382
///
4483
/// # Examples
4584
///
4685
/// ```
47-
/// use crate::path::Path;
86+
/// use async_std::path::Path;
4887
///
4988
/// Path::new("foo.txt");
5089
/// ```
5190
///
5291
/// You can create `Path`s from `String`s, or even other `Path`s:
5392
///
5493
/// ```
55-
/// use crate::path::Path;
94+
/// use async_std::path::Path;
5695
///
5796
/// let string = String::from("foo.txt");
5897
/// let from_string = Path::new(&string);
@@ -70,7 +109,7 @@ impl Path {
70109
/// # Examples
71110
///
72111
/// ```
73-
/// use crate::path::{Path, PathBuf};
112+
/// use async_std::path::{Path, PathBuf};
74113
///
75114
/// let path_buf = Path::new("foo.txt").to_path_buf();
76115
/// assert_eq!(path_buf, PathBuf::from("foo.txt"));
@@ -98,8 +137,40 @@ impl AsRef<Path> for Path {
98137
}
99138
}
100139

140+
impl AsRef<Path> for OsStr {
141+
fn as_ref(&self) -> &Path {
142+
Path::new(self)
143+
}
144+
}
145+
146+
impl AsRef<Path> for str {
147+
fn as_ref(&self) -> &Path {
148+
Path::new(self)
149+
}
150+
}
151+
101152
impl std::fmt::Debug for Path {
102153
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
103154
std::fmt::Debug::fmt(&self.inner, formatter)
104155
}
105156
}
157+
158+
impl std::cmp::PartialEq for Path {
159+
fn eq(&self, other: &Path) -> bool {
160+
self.components().eq(other.components())
161+
}
162+
}
163+
164+
impl std::cmp::Eq for Path {}
165+
166+
impl std::cmp::PartialOrd for Path {
167+
fn partial_cmp(&self, other: &Path) -> Option<std::cmp::Ordering> {
168+
self.components().partial_cmp(other.components())
169+
}
170+
}
171+
172+
impl std::cmp::Ord for Path {
173+
fn cmp(&self, other: &Path) -> std::cmp::Ordering {
174+
self.components().cmp(other.components())
175+
}
176+
}

src/path/pathbuf.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
use std::ffi::OsString;
22

3+
use crate::path::Path;
4+
35
/// This struct is an async version of [`std::path::PathBuf`].
46
///
57
/// [`std::path::Path`]: https://doc.rust-lang.org/std/path/struct.PathBuf.html
@@ -27,6 +29,12 @@ impl From<OsString> for PathBuf {
2729
}
2830
}
2931

32+
impl AsRef<Path> for PathBuf {
33+
fn as_ref(&self) -> &Path {
34+
Path::new(&self.inner)
35+
}
36+
}
37+
3038
impl std::fmt::Debug for PathBuf {
3139
fn fmt(&self, formatter: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3240
std::fmt::Debug::fmt(&self.inner, formatter)

0 commit comments

Comments
 (0)