Skip to content

Cleanup path module #497

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
4 commits merged into from Nov 10, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/path/components.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::ffi::OsStr;
use std::iter::FusedIterator;

use crate::path::{Component, Path};

/// An iterator over the [`Component`]s of a [`Path`].
///
/// This `struct` is created by the [`components`] method on [`Path`].
/// See its documentation for more.
///
/// # Examples
///
/// ```
/// use async_std::path::Path;
///
/// let path = Path::new("/tmp/foo/bar.txt");
///
/// for component in path.components() {
/// println!("{:?}", component);
/// }
/// ```
///
/// [`Component`]: enum.Component.html
/// [`components`]: struct.Path.html#method.components
/// [`Path`]: struct.Path.html
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Components<'a> {
pub(crate) inner: std::path::Components<'a>,
}

impl<'a> Components<'a> {
/// Extracts a slice corresponding to the portion of the path remaining for iteration.
///
/// # Examples
///
/// ```
/// use async_std::path::Path;
///
/// let mut components = Path::new("/tmp/foo/bar.txt").components();
/// components.next();
/// components.next();
///
/// assert_eq!(Path::new("foo/bar.txt"), components.as_path());
/// ```
pub fn as_path(&self) -> &'a Path {
self.inner.as_path().into()
}
}

impl AsRef<Path> for Components<'_> {
fn as_ref(&self) -> &Path {
self.as_path()
}
}

impl AsRef<OsStr> for Components<'_> {
fn as_ref(&self) -> &OsStr {
self.as_path().as_os_str()
}
}

impl<'a> Iterator for Components<'a> {
type Item = Component<'a>;

fn next(&mut self) -> Option<Component<'a>> {
self.inner.next()
}
}

impl<'a> DoubleEndedIterator for Components<'a> {
fn next_back(&mut self) -> Option<Component<'a>> {
self.inner.next_back()
}
}

impl FusedIterator for Components<'_> {}

impl AsRef<Path> for Component<'_> {
fn as_ref(&self) -> &Path {
self.as_os_str().as_ref()
}
}
82 changes: 82 additions & 0 deletions src/path/iter.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
use std::ffi::OsStr;
use std::fmt;
use std::iter::FusedIterator;

use crate::path::{Component, Components, Path};

/// An iterator over the [`Component`]s of a [`Path`], as [`OsStr`] slices.
///
/// This `struct` is created by the [`iter`] method on [`Path`].
/// See its documentation for more.
///
/// [`Component`]: enum.Component.html
/// [`iter`]: struct.Path.html#method.iter
/// [`OsStr`]: ../../std/ffi/struct.OsStr.html
/// [`Path`]: struct.Path.html
#[derive(Clone)]
pub struct Iter<'a> {
pub(crate) inner: Components<'a>,
}

impl<'a> Iter<'a> {
/// Extracts a slice corresponding to the portion of the path remaining for iteration.
///
/// # Examples
///
/// ```
/// use async_std::path::Path;
///
/// let mut iter = Path::new("/tmp/foo/bar.txt").iter();
/// iter.next();
/// iter.next();
///
/// assert_eq!(Path::new("foo/bar.txt"), iter.as_path());
/// ```
pub fn as_path(&self) -> &'a Path {
self.inner.as_path()
}
}

impl<'a> Iterator for Iter<'a> {
type Item = &'a OsStr;

fn next(&mut self) -> Option<&'a OsStr> {
self.inner.next().map(Component::as_os_str)
}
}

impl fmt::Debug for Iter<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
struct DebugHelper<'a>(&'a Path);

impl fmt::Debug for DebugHelper<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_list().entries(self.0.iter()).finish()
}
}

f.debug_tuple("Iter")
.field(&DebugHelper(self.as_path()))
.finish()
}
}

impl AsRef<Path> for Iter<'_> {
fn as_ref(&self) -> &Path {
self.as_path()
}
}

impl AsRef<OsStr> for Iter<'_> {
fn as_ref(&self) -> &OsStr {
self.as_path().as_os_str()
}
}

impl<'a> DoubleEndedIterator for Iter<'a> {
fn next_back(&mut self) -> Option<&'a OsStr> {
self.inner.next_back().map(Component::as_os_str)
}
}

impl FusedIterator for Iter<'_> {}
23 changes: 8 additions & 15 deletions src/path/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,25 +70,18 @@
//! [`OsStr`]: https://doc.rust-lang.org/std/ffi/struct.OsStr.html

mod ancestors;
mod components;
mod iter;
mod path;
mod pathbuf;

// Structs re-export
#[doc(inline)]
pub use std::path::{Components, Display, Iter, PrefixComponent, StripPrefixError};
pub use std::path::{
is_separator, Component, Display, Prefix, PrefixComponent, StripPrefixError, MAIN_SEPARATOR,
};

// Enums re-export
#[doc(inline)]
pub use std::path::{Component, Prefix};

// Constants re-export
#[doc(inline)]
pub use std::path::MAIN_SEPARATOR;

// Functions re-export
#[doc(inline)]
pub use std::path::is_separator;

use ancestors::Ancestors;
pub use ancestors::Ancestors;
pub use components::Components;
pub use iter::Iter;
pub use path::Path;
pub use pathbuf::PathBuf;
Loading