From 2d0a9ffbccf9d8a4773eb6efa48ddc6978af6455 Mon Sep 17 00:00:00 2001
From: David Sherret <dsherret@users.noreply.github.com>
Date: Thu, 6 Apr 2023 12:53:53 -0400
Subject: [PATCH] refactor(ext/node): `NodeFs` - add back altered metadata
 method (#18613)

From https://github.com/denoland/deno/pull/18604/files#r1159992299

We should still have a `metadata` method because it's one system call
instead of two on most platforms.
---
 ext/node/lib.rs | 19 +++++++++++++++++++
 ext/node/ops.rs |  4 ++--
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/ext/node/lib.rs b/ext/node/lib.rs
index ec3e7ab25a..478efaf278 100644
--- a/ext/node/lib.rs
+++ b/ext/node/lib.rs
@@ -50,8 +50,15 @@ pub trait NodePermissions {
   fn check_read(&mut self, path: &Path) -> Result<(), AnyError>;
 }
 
+#[derive(Default, Clone)]
+pub struct NodeFsMetadata {
+  pub is_file: bool,
+  pub is_dir: bool,
+}
+
 pub trait NodeFs {
   fn current_dir() -> io::Result<PathBuf>;
+  fn metadata<P: AsRef<Path>>(path: P) -> io::Result<NodeFsMetadata>;
   fn is_file<P: AsRef<Path>>(path: P) -> bool;
   fn is_dir<P: AsRef<Path>>(path: P) -> bool;
   fn exists<P: AsRef<Path>>(path: P) -> bool;
@@ -66,6 +73,18 @@ impl NodeFs for RealFs {
     std::env::current_dir()
   }
 
+  fn metadata<P: AsRef<Path>>(path: P) -> io::Result<NodeFsMetadata> {
+    #[allow(clippy::disallowed_methods)]
+    std::fs::metadata(path).map(|metadata| {
+      // on most systems, calling is_file() and is_dir() is cheap
+      // and returns information already found in the metadata object
+      NodeFsMetadata {
+        is_file: metadata.is_file(),
+        is_dir: metadata.is_dir(),
+      }
+    })
+  }
+
   fn exists<P: AsRef<Path>>(path: P) -> bool {
     #[allow(clippy::disallowed_methods)]
     std::fs::metadata(path).is_ok()
diff --git a/ext/node/ops.rs b/ext/node/ops.rs
index 77d148383b..3db23b5eaf 100644
--- a/ext/node/ops.rs
+++ b/ext/node/ops.rs
@@ -264,8 +264,8 @@ where
 {
   let path = PathBuf::from(path);
   ensure_read_permission::<Env::P>(state, &path)?;
-  if Env::Fs::exists(&path) {
-    if Env::Fs::is_file(&path) {
+  if let Ok(metadata) = Env::Fs::metadata(&path) {
+    if metadata.is_file {
       return Ok(0);
     } else {
       return Ok(1);