From ba87048db559b3b892bf8ebc3901c65ddd352259 Mon Sep 17 00:00:00 2001 From: Wouter Geraedts Date: Mon, 14 Oct 2019 22:00:45 +0200 Subject: [PATCH] Implemented our own Path::ancestors iterator --- src/path/mod.rs | 4 ++-- src/path/path.rs | 41 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 41 insertions(+), 4 deletions(-) diff --git a/src/path/mod.rs b/src/path/mod.rs index 35a6717..9b8cdc9 100644 --- a/src/path/mod.rs +++ b/src/path/mod.rs @@ -9,7 +9,7 @@ mod pathbuf; // Structs re-export #[doc(inline)] -pub use std::path::{Ancestors, Components, Display, Iter, PrefixComponent, StripPrefixError}; +pub use std::path::{Components, Display, Iter, PrefixComponent, StripPrefixError}; // Enums re-export #[doc(inline)] @@ -23,5 +23,5 @@ pub use std::path::MAIN_SEPARATOR; #[doc(inline)] pub use std::path::is_separator; -pub use path::Path; +pub use path::{Ancestors, Path}; pub use pathbuf::PathBuf; diff --git a/src/path/path.rs b/src/path/path.rs index 21ab5e2..e66c6c2 100644 --- a/src/path/path.rs +++ b/src/path/path.rs @@ -1,6 +1,7 @@ use std::ffi::OsStr; +use std::iter::FusedIterator; -use crate::path::{Ancestors, Components, Display, Iter, PathBuf, StripPrefixError}; +use crate::path::{Components, Display, Iter, PathBuf, StripPrefixError}; use crate::{fs, io}; /// This struct is an async version of [`std::path::Path`]. @@ -35,7 +36,7 @@ impl Path { /// [`None`]: https://doc.rust-lang.org/std/option/enum.Option.html /// [`parent`]: struct.Path.html#method.parent pub fn ancestors(&self) -> Ancestors<'_> { - self.inner.ancestors() + Ancestors { next: Some(&self) } } /// Yields the underlying [`OsStr`] slice. @@ -752,6 +753,42 @@ impl Path { } } +/// An iterator over [`Path`] and its ancestors. +/// +/// This `struct` is created by the [`ancestors`] method on [`Path`]. +/// See its documentation for more. +/// +/// # Examples +/// +/// ``` +/// use async_std::path::Path; +/// +/// let path = Path::new("/foo/bar"); +/// +/// for ancestor in path.ancestors() { +/// println!("{}", ancestor.display()); +/// } +/// ``` +/// +/// [`ancestors`]: struct.Path.html#method.ancestors +/// [`Path`]: struct.Path.html +#[derive(Copy, Clone, Debug)] +pub struct Ancestors<'a> { + next: Option<&'a Path>, +} + +impl<'a> Iterator for Ancestors<'a> { + type Item = &'a Path; + + fn next(&mut self) -> Option { + let next = self.next; + self.next = next.and_then(Path::parent); + next + } +} + +impl FusedIterator for Ancestors<'_> {} + impl<'a> From<&'a std::path::Path> for &'a Path { fn from(path: &'a std::path::Path) -> &'a Path { &Path::new(path.as_os_str())