Skip to content

Commit 417b548

Browse files
author
Stjepan Glavina
authored
Cleanup path module (#497)
* Cleanup path module * Derive clone for PathBuf and remove unused import * impl AsRef<Path> for std::path::PathBuf * Fix a doc comment
1 parent 122e873 commit 417b548

File tree

5 files changed

+575
-124
lines changed

5 files changed

+575
-124
lines changed

src/path/components.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use std::ffi::OsStr;
2+
use std::iter::FusedIterator;
3+
4+
use crate::path::{Component, Path};
5+
6+
/// An iterator over the [`Component`]s of a [`Path`].
7+
///
8+
/// This `struct` is created by the [`components`] method on [`Path`].
9+
/// See its documentation for more.
10+
///
11+
/// # Examples
12+
///
13+
/// ```
14+
/// use async_std::path::Path;
15+
///
16+
/// let path = Path::new("/tmp/foo/bar.txt");
17+
///
18+
/// for component in path.components() {
19+
/// println!("{:?}", component);
20+
/// }
21+
/// ```
22+
///
23+
/// [`Component`]: enum.Component.html
24+
/// [`components`]: struct.Path.html#method.components
25+
/// [`Path`]: struct.Path.html
26+
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
27+
pub struct Components<'a> {
28+
pub(crate) inner: std::path::Components<'a>,
29+
}
30+
31+
impl<'a> Components<'a> {
32+
/// Extracts a slice corresponding to the portion of the path remaining for iteration.
33+
///
34+
/// # Examples
35+
///
36+
/// ```
37+
/// use async_std::path::Path;
38+
///
39+
/// let mut components = Path::new("/tmp/foo/bar.txt").components();
40+
/// components.next();
41+
/// components.next();
42+
///
43+
/// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
44+
/// ```
45+
pub fn as_path(&self) -> &'a Path {
46+
self.inner.as_path().into()
47+
}
48+
}
49+
50+
impl AsRef<Path> for Components<'_> {
51+
fn as_ref(&self) -> &Path {
52+
self.as_path()
53+
}
54+
}
55+
56+
impl AsRef<OsStr> for Components<'_> {
57+
fn as_ref(&self) -> &OsStr {
58+
self.as_path().as_os_str()
59+
}
60+
}
61+
62+
impl<'a> Iterator for Components<'a> {
63+
type Item = Component<'a>;
64+
65+
fn next(&mut self) -> Option<Component<'a>> {
66+
self.inner.next()
67+
}
68+
}
69+
70+
impl<'a> DoubleEndedIterator for Components<'a> {
71+
fn next_back(&mut self) -> Option<Component<'a>> {
72+
self.inner.next_back()
73+
}
74+
}
75+
76+
impl FusedIterator for Components<'_> {}
77+
78+
impl AsRef<Path> for Component<'_> {
79+
fn as_ref(&self) -> &Path {
80+
self.as_os_str().as_ref()
81+
}
82+
}

src/path/iter.rs

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
use std::ffi::OsStr;
2+
use std::fmt;
3+
use std::iter::FusedIterator;
4+
5+
use crate::path::{Component, Components, Path};
6+
7+
/// An iterator over the [`Component`]s of a [`Path`], as [`OsStr`] slices.
8+
///
9+
/// This `struct` is created by the [`iter`] method on [`Path`].
10+
/// See its documentation for more.
11+
///
12+
/// [`Component`]: enum.Component.html
13+
/// [`iter`]: struct.Path.html#method.iter
14+
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
15+
/// [`Path`]: struct.Path.html
16+
#[derive(Clone)]
17+
pub struct Iter<'a> {
18+
pub(crate) inner: Components<'a>,
19+
}
20+
21+
impl<'a> Iter<'a> {
22+
/// Extracts a slice corresponding to the portion of the path remaining for iteration.
23+
///
24+
/// # Examples
25+
///
26+
/// ```
27+
/// use async_std::path::Path;
28+
///
29+
/// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
30+
/// iter.next();
31+
/// iter.next();
32+
///
33+
/// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
34+
/// ```
35+
pub fn as_path(&self) -> &'a Path {
36+
self.inner.as_path()
37+
}
38+
}
39+
40+
impl<'a> Iterator for Iter<'a> {
41+
type Item = &'a OsStr;
42+
43+
fn next(&mut self) -> Option<&'a OsStr> {
44+
self.inner.next().map(Component::as_os_str)
45+
}
46+
}
47+
48+
impl fmt::Debug for Iter<'_> {
49+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
50+
struct DebugHelper<'a>(&'a Path);
51+
52+
impl fmt::Debug for DebugHelper<'_> {
53+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
54+
f.debug_list().entries(self.0.iter()).finish()
55+
}
56+
}
57+
58+
f.debug_tuple("Iter")
59+
.field(&DebugHelper(self.as_path()))
60+
.finish()
61+
}
62+
}
63+
64+
impl AsRef<Path> for Iter<'_> {
65+
fn as_ref(&self) -> &Path {
66+
self.as_path()
67+
}
68+
}
69+
70+
impl AsRef<OsStr> for Iter<'_> {
71+
fn as_ref(&self) -> &OsStr {
72+
self.as_path().as_os_str()
73+
}
74+
}
75+
76+
impl<'a> DoubleEndedIterator for Iter<'a> {
77+
fn next_back(&mut self) -> Option<&'a OsStr> {
78+
self.inner.next_back().map(Component::as_os_str)
79+
}
80+
}
81+
82+
impl FusedIterator for Iter<'_> {}

src/path/mod.rs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -70,25 +70,18 @@
7070
//! [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html
7171
7272
mod ancestors;
73+
mod components;
74+
mod iter;
7375
mod path;
7476
mod pathbuf;
7577

76-
// Structs re-export
7778
#[doc(inline)]
78-
pub use std::path::{Components, Display, Iter, PrefixComponent, StripPrefixError};
79+
pub use std::path::{
80+
is_separator, Component, Display, Prefix, PrefixComponent, StripPrefixError, MAIN_SEPARATOR,
81+
};
7982

80-
// Enums re-export
81-
#[doc(inline)]
82-
pub use std::path::{Component, Prefix};
83-
84-
// Constants re-export
85-
#[doc(inline)]
86-
pub use std::path::MAIN_SEPARATOR;
87-
88-
// Functions re-export
89-
#[doc(inline)]
90-
pub use std::path::is_separator;
91-
92-
use ancestors::Ancestors;
83+
pub use ancestors::Ancestors;
84+
pub use components::Components;
85+
pub use iter::Iter;
9386
pub use path::Path;
9487
pub use pathbuf::PathBuf;

0 commit comments

Comments
 (0)