]> git.lizzy.rs Git - rust.git/commitdiff
Add std::path::Path::ancestors
authorTobias Stolzmann <tobias.stolzmann@gmail.com>
Wed, 28 Feb 2018 14:29:16 +0000 (15:29 +0100)
committerTobias Stolzmann <tobias.stolzmann@gmail.com>
Wed, 28 Feb 2018 14:29:16 +0000 (15:29 +0100)
Squashed commit of the following:

commit 1b5d55e26f667b1a25c83c5db0cbb072013a5122
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Wed Feb 28 00:06:15 2018 +0100

    Bugfix

commit 4265c2db0b0aaa66fdeace5d329665fd2d13903a
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Tue Feb 27 22:59:12 2018 +0100

    Rename std::path::Path::parents into std::path::Path::ancestors

commit 2548e4b14d377d20adad0f08304a0dd6f8e48e23
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Tue Feb 27 12:50:37 2018 +0100

    Add tracking issue

commit 3e2ce51a6eea0e39af05849f76dd2cefd5035e86
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Mon Feb 26 15:05:15 2018 +0100

    impl FusedIterator for Parents

commit a7e096420809740311e19d963d4aba6df77be2f9
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Mon Feb 26 14:38:41 2018 +0100

    Clarify that the iterator returned will yield at least one value

commit 796a36ea203cd197cc4c810eebd21c7e3433e6f1
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Thu Feb 22 14:01:21 2018 +0100

    Fix examples

commit e279383b21f11c97269cb355a5b2a0ecdb65bb0c
Author: Tobias Stolzmann <tobias.stolzmann@gmail.com>
Date:   Thu Feb 22 04:47:24 2018 +0100

    Add std::path::Path::parents

src/libstd/path.rs

index 4bbad30a5a3152cac16732144274c154196b6bf1..1608a752a463fdac287f7d309d9068fd10a659d8 100644 (file)
@@ -1035,6 +1035,50 @@ fn cmp(&self, other: &Components<'a>) -> cmp::Ordering {
     }
 }
 
+/// An iterator over [`Path`] and its ancestors.
+///
+/// This `struct` is created by the [`ancestors`] method on [`Path`].
+/// See its documentation for more.
+///
+/// # Examples
+///
+/// ```
+/// #![feature(path_ancestors)]
+///
+/// use 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)]
+#[unstable(feature = "path_ancestors", issue = "48581")]
+pub struct Ancestors<'a> {
+    next: Option<&'a Path>,
+}
+
+#[unstable(feature = "path_ancestors", issue = "48581")]
+impl<'a> Iterator for Ancestors<'a> {
+    type Item = &'a Path;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let next = self.next;
+        self.next = match next {
+            Some(path) => path.parent(),
+            None => None,
+        };
+        next
+    }
+}
+
+#[unstable(feature = "fused", issue = "35602")]
+impl<'a> FusedIterator for Ancestors<'a> {}
+
 ////////////////////////////////////////////////////////////////////////////////
 // Basic types and traits
 ////////////////////////////////////////////////////////////////////////////////
@@ -1820,6 +1864,37 @@ pub fn parent(&self) -> Option<&Path> {
         })
     }
 
+    /// Produces an iterator over `Path` and its ancestors.
+    ///
+    /// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero
+    /// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`,
+    /// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns
+    /// [`None`], the iterator will do likewise. The iterator will always yield at least one value,
+    /// namely `&self`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(path_ancestors)]
+    ///
+    /// use std::path::Path;
+    ///
+    /// let mut ancestors = Path::new("/foo/bar").ancestors();
+    /// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
+    /// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
+    /// assert_eq!(ancestors.next(), Some(Path::new("/")));
+    /// assert_eq!(ancestors.next(), None);
+    /// ```
+    ///
+    /// [`None`]: ../../std/option/enum.Option.html#variant.None
+    /// [`parent`]: struct.Path.html#method.parent
+    #[unstable(feature = "path_ancestors", issue = "48581")]
+    pub fn ancestors(&self) -> Ancestors {
+        Ancestors {
+            next: Some(&self),
+        }
+    }
+
     /// Returns the final component of the `Path`, if there is one.
     ///
     /// If the path is a normal file, this is the file name. If it's the path of a directory, this