about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <huyuumi.dev@gmail.com>2021-03-16 23:53:52 +0900
committerGitHub <noreply@github.com>2021-03-16 23:53:52 +0900
commit62d38da9fab089520b0e10e71a54be0d30b0490a (patch)
treeba3cc8360b17d7ae546fc31d410bcbab9c691ca4
parentf24ce9b0140d9be5a336954e878d0c1522966bb8 (diff)
parent4330268181c3de234457138f23bb821afd0c181e (diff)
downloadrust-62d38da9fab089520b0e10e71a54be0d30b0490a.tar.gz
rust-62d38da9fab089520b0e10e71a54be0d30b0490a.zip
Rollup merge of #81822 - Kixunil:path_try_exists, r=kennytm
Added `try_exists()` method to `std::path::Path`

This method is similar to the existing `exists()` method, except it
doesn't silently ignore the errors, leading to less error-prone code.

This change intentionally does NOT touch the documentation of `exists()`
nor recommend people to use this method while it's unstable.
Such changes are reserved for stabilization to prevent confusing people.

Apart from that it avoids conflicts with #80979.

`@joshtriplett` requested this PR in [internals discussion](https://internals.rust-lang.org/t/the-api-of-path-exists-encourages-broken-code/13817/25?u=kixunil)
-rw-r--r--library/std/src/path.rs30
1 files changed, 30 insertions, 0 deletions
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index de3b57df44e..57c892f32b1 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2472,6 +2472,36 @@ impl Path {
         fs::metadata(self).is_ok()
     }
 
+    /// Returns `Ok(true)` if the path points at an existing entity.
+    ///
+    /// This function will traverse symbolic links to query information about the
+    /// destination file. In case of broken symbolic links this will return `Ok(false)`.
+    ///
+    /// As opposed to the `exists()` method, this one doesn't silently ignore errors
+    /// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
+    /// denied on some of the parent directories.)
+    ///
+    /// # Examples
+    ///
+    /// ```no_run
+    /// #![feature(path_try_exists)]
+    ///
+    /// use std::path::Path;
+    /// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
+    /// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
+    /// ```
+    // FIXME: stabilization should modify documentation of `exists()` to recommend this method
+    // instead.
+    #[unstable(feature = "path_try_exists", issue = "83186")]
+    #[inline]
+    pub fn try_exists(&self) -> io::Result<bool> {
+        match fs::metadata(self) {
+            Ok(_) => Ok(true),
+            Err(error) if error.kind() == io::ErrorKind::NotFound => Ok(false),
+            Err(error) => Err(error),
+        }
+    }
+
     /// Returns `true` if the path exists on disk and is pointing at a regular file.
     ///
     /// This function will traverse symbolic links to query information about the