Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update to latest code head
  • Loading branch information
kevinkassimo committed Feb 20, 2023
commit ec6bc2c08323b10508ad84d96de0a7df53f2b2a6
14 changes: 6 additions & 8 deletions tokio/src/fs/try_exists.rs
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
use crate::fs::asyncify;

use std::io;
use std::path::Path;

/// 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)`.
///
/// This is the async equivalent of [`std::fs::try_exists`][std].
/// This is the async equivalent of [`std::path::Path::try_exists`][std].
///
/// [std]: fn@std::fs::try_exists
/// [std]: fn@std::path::Path::try_exists
///
/// # Examples
///
Expand All @@ -21,11 +23,7 @@ use std::path::Path;
/// # }
/// ```

pub async fn try_exists(path: impl AsRef<Path>) -> Result<bool, std::io::Error> {
pub async fn try_exists(path: impl AsRef<Path>) -> io::Result<bool> {
let path = path.as_ref().to_owned();
match asyncify(move || std::fs::metadata(path)).await {
Ok(_) => Ok(true),
Err(error) if error.kind() == std::io::ErrorKind::NotFound => Ok(false),
Err(error) => Err(error),
}
asyncify(move || path.as_path().try_exists()).await
}
41 changes: 41 additions & 0 deletions tokio/tests/fs_try_exists.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#![warn(rust_2018_idioms)]
#![cfg(all(feature = "full", not(tokio_wasi)))] // Wasi does not support file operations

use std::os::unix::prelude::PermissionsExt;

use tempfile::tempdir;
use tokio::fs;

#[tokio::test]
async fn try_exists() {
let dir = tempdir().unwrap();

let existing_path = dir.path().join("foo.txt");
fs::write(&existing_path, b"Hello File!").await.unwrap();
let nonexisting_path = dir.path().join("bar.txt");

assert_eq!(fs::try_exists(existing_path).await.unwrap(), true);
assert_eq!(fs::try_exists(nonexisting_path).await.unwrap(), false);

let permission_denied_directory_path = dir.path().join("baz");
fs::create_dir(&permission_denied_directory_path)
.await
.unwrap();
let permission_denied_file_path = permission_denied_directory_path.join("baz.txt");
fs::write(&permission_denied_file_path, b"Hello File!")
.await
.unwrap();
let mut perms = tokio::fs::metadata(&permission_denied_directory_path)
.await
.unwrap()
.permissions();
perms.set_mode(0o244);
fs::set_permissions(&permission_denied_directory_path, perms)
.await
.unwrap();
let permission_denied_result = fs::try_exists(permission_denied_file_path).await;
assert_eq!(
permission_denied_result.err().unwrap().kind(),
std::io::ErrorKind::PermissionDenied
);
}