aboutsummaryrefslogtreecommitdiff
path: root/ctr-std/src/path.rs
diff options
context:
space:
mode:
authorFenrirWolf <[email protected]>2018-06-10 11:49:19 -0600
committerGitHub <[email protected]>2018-06-10 11:49:19 -0600
commit49041a4e56a4cab33ae7889537d33670e8b012fb (patch)
tree0c931e8716200f9aa8c7daef47b62474d0285d5c /ctr-std/src/path.rs
parentMerge pull request #69 from FenrirWolf/libctru-1.5.0 (diff)
parentFixes according to Fenrir's review (diff)
downloadctru-rs-49041a4e56a4cab33ae7889537d33670e8b012fb.tar.xz
ctru-rs-49041a4e56a4cab33ae7889537d33670e8b012fb.zip
Merge pull request #68 from linouxis9/master
Update for latest nightly 2018-05-06
Diffstat (limited to 'ctr-std/src/path.rs')
-rw-r--r--ctr-std/src/path.rs108
1 files changed, 92 insertions, 16 deletions
diff --git a/ctr-std/src/path.rs b/ctr-std/src/path.rs
index 2b76a2d..861c7dd 100644
--- a/ctr-std/src/path.rs
+++ b/ctr-std/src/path.rs
@@ -201,7 +201,7 @@ impl<'a> Prefix<'a> {
os_str_as_u8_slice(s).len()
}
match *self {
- #[cfg(target_os = "horizon")]
+ #[cfg(target_os = "horizon")]
Verbatim(x) => 1 + os_str_len(x),
#[cfg(target_os = "windows")]
Verbatim(x) => 4 + os_str_len(x),
@@ -300,10 +300,9 @@ pub const MAIN_SEPARATOR: char = ::sys::path::MAIN_SEP;
// Iterate through `iter` while it matches `prefix`; return `None` if `prefix`
// is not a prefix of `iter`, otherwise return `Some(iter_after_prefix)` giving
// `iter` after having exhausted `prefix`.
-fn iter_after<A, I, J>(mut iter: I, mut prefix: J) -> Option<I>
- where I: Iterator<Item = A> + Clone,
- J: Iterator<Item = A>,
- A: PartialEq
+fn iter_after<'a, 'b, I, J>(mut iter: I, mut prefix: J) -> Option<I>
+ where I: Iterator<Item = Component<'a>> + Clone,
+ J: Iterator<Item = Component<'b>>,
{
loop {
let mut iter_next = iter.clone();
@@ -328,8 +327,7 @@ unsafe fn u8_slice_as_os_str(s: &[u8]) -> &OsStr {
// Detect scheme on Redox
fn has_redox_scheme(s: &[u8]) -> bool {
- (cfg!(target_os = "redox") || cfg!(target_os = "horizon"))
- && s.split(|b| *b == b'/').next().unwrap_or(b"").contains(&b':')
+ cfg!(target_os = "redox") && s.split(|b| *b == b'/').next().unwrap_or(b"").contains(&b':')
}
////////////////////////////////////////////////////////////////////////////////
@@ -909,7 +907,7 @@ impl<'a> DoubleEndedIterator for Iter<'a> {
}
}
-#[unstable(feature = "fused", issue = "35602")]
+#[stable(feature = "fused", since = "1.26.0")]
impl<'a> FusedIterator for Iter<'a> {}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1012,7 +1010,7 @@ impl<'a> DoubleEndedIterator for Components<'a> {
}
}
-#[unstable(feature = "fused", issue = "35602")]
+#[stable(feature = "fused", since = "1.26.0")]
impl<'a> FusedIterator for Components<'a> {}
#[stable(feature = "rust1", since = "1.0.0")]
@@ -1039,6 +1037,50 @@ impl<'a> cmp::Ord for Components<'a> {
}
}
+/// 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 = "path_ancestors", issue = "48581")]
+impl<'a> FusedIterator for Ancestors<'a> {}
+
////////////////////////////////////////////////////////////////////////////////
// Basic types and traits
////////////////////////////////////////////////////////////////////////////////
@@ -1740,7 +1782,7 @@ impl Path {
#[stable(feature = "rust1", since = "1.0.0")]
#[allow(deprecated)]
pub fn is_absolute(&self) -> bool {
- if cfg!(target_os = "redox") || cfg!(target_os = "horizon") {
+ if cfg!(target_os = "redox") {
// FIXME: Allow Redox prefixes
self.has_root() || has_redox_scheme(self.as_u8_slice())
} else {
@@ -1824,12 +1866,43 @@ impl 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
/// is the directory name.
///
- /// Returns [`None`] If the path terminates in `..`.
+ /// Returns [`None`] if the path terminates in `..`.
///
/// [`None`]: ../../std/option/enum.Option.html#variant.None
///
@@ -1869,7 +1942,7 @@ impl Path {
/// # Examples
///
/// ```
- /// use std::path::Path;
+ /// use std::path::{Path, PathBuf};
///
/// let path = Path::new("/test/haha/foo.txt");
///
@@ -1880,17 +1953,20 @@ impl Path {
/// assert_eq!(path.strip_prefix("/test/haha/foo.txt/"), Ok(Path::new("")));
/// assert_eq!(path.strip_prefix("test").is_ok(), false);
/// assert_eq!(path.strip_prefix("/haha").is_ok(), false);
+ ///
+ /// let prefix = PathBuf::from("/test/");
+ /// assert_eq!(path.strip_prefix(prefix), Ok(Path::new("haha/foo.txt")));
/// ```
#[stable(since = "1.7.0", feature = "path_strip_prefix")]
- pub fn strip_prefix<'a, P: ?Sized>(&'a self, base: &'a P)
- -> Result<&'a Path, StripPrefixError>
+ pub fn strip_prefix<P>(&self, base: P)
+ -> Result<&Path, StripPrefixError>
where P: AsRef<Path>
{
self._strip_prefix(base.as_ref())
}
- fn _strip_prefix<'a>(&'a self, base: &'a Path)
- -> Result<&'a Path, StripPrefixError> {
+ fn _strip_prefix(&self, base: &Path)
+ -> Result<&Path, StripPrefixError> {
iter_after(self.components(), base.components())
.map(|c| c.as_path())
.ok_or(StripPrefixError(()))