Skip to content

Commit 6b5519d

Browse files
committed
Rollup merge of rust-lang#48420 - teiesti:path_parents, r=BurntSushi
Fixes rust-lang#47311. r? @nrc
2 parents 1251560 + b9e9b4a commit 6b5519d

File tree

1 file changed

+75
-0
lines changed

1 file changed

+75
-0
lines changed

src/libstd/path.rs

+75
Original file line numberDiff line numberDiff line change
@@ -1035,6 +1035,50 @@ impl<'a> cmp::Ord for Components<'a> {
10351035
}
10361036
}
10371037

1038+
/// An iterator over [`Path`] and its ancestors.
1039+
///
1040+
/// This `struct` is created by the [`ancestors`] method on [`Path`].
1041+
/// See its documentation for more.
1042+
///
1043+
/// # Examples
1044+
///
1045+
/// ```
1046+
/// #![feature(path_ancestors)]
1047+
///
1048+
/// use std::path::Path;
1049+
///
1050+
/// let path = Path::new("/foo/bar");
1051+
///
1052+
/// for ancestor in path.ancestors() {
1053+
/// println!("{}", ancestor.display());
1054+
/// }
1055+
/// ```
1056+
///
1057+
/// [`ancestors`]: struct.Path.html#method.ancestors
1058+
/// [`Path`]: struct.Path.html
1059+
#[derive(Copy, Clone, Debug)]
1060+
#[unstable(feature = "path_ancestors", issue = "48581")]
1061+
pub struct Ancestors<'a> {
1062+
next: Option<&'a Path>,
1063+
}
1064+
1065+
#[unstable(feature = "path_ancestors", issue = "48581")]
1066+
impl<'a> Iterator for Ancestors<'a> {
1067+
type Item = &'a Path;
1068+
1069+
fn next(&mut self) -> Option<Self::Item> {
1070+
let next = self.next;
1071+
self.next = match next {
1072+
Some(path) => path.parent(),
1073+
None => None,
1074+
};
1075+
next
1076+
}
1077+
}
1078+
1079+
#[unstable(feature = "fused", issue = "35602")]
1080+
impl<'a> FusedIterator for Ancestors<'a> {}
1081+
10381082
////////////////////////////////////////////////////////////////////////////////
10391083
// Basic types and traits
10401084
////////////////////////////////////////////////////////////////////////////////
@@ -1820,6 +1864,37 @@ impl Path {
18201864
})
18211865
}
18221866

1867+
/// Produces an iterator over `Path` and its ancestors.
1868+
///
1869+
/// The iterator will yield the `Path` that is returned if the [`parent`] method is used zero
1870+
/// or more times. That means, the iterator will yield `&self`, `&self.parent().unwrap()`,
1871+
/// `&self.parent().unwrap().parent().unwrap()` and so on. If the [`parent`] method returns
1872+
/// [`None`], the iterator will do likewise. The iterator will always yield at least one value,
1873+
/// namely `&self`.
1874+
///
1875+
/// # Examples
1876+
///
1877+
/// ```
1878+
/// #![feature(path_ancestors)]
1879+
///
1880+
/// use std::path::Path;
1881+
///
1882+
/// let mut ancestors = Path::new("/foo/bar").ancestors();
1883+
/// assert_eq!(ancestors.next(), Some(Path::new("/foo/bar")));
1884+
/// assert_eq!(ancestors.next(), Some(Path::new("/foo")));
1885+
/// assert_eq!(ancestors.next(), Some(Path::new("/")));
1886+
/// assert_eq!(ancestors.next(), None);
1887+
/// ```
1888+
///
1889+
/// [`None`]: ../../std/option/enum.Option.html#variant.None
1890+
/// [`parent`]: struct.Path.html#method.parent
1891+
#[unstable(feature = "path_ancestors", issue = "48581")]
1892+
pub fn ancestors(&self) -> Ancestors {
1893+
Ancestors {
1894+
next: Some(&self),
1895+
}
1896+
}
1897+
18231898
/// Returns the final component of the `Path`, if there is one.
18241899
///
18251900
/// If the path is a normal file, this is the file name. If it's the path of a directory, this

0 commit comments

Comments
 (0)