diff options
author | Divy Srivastava <dj.srivastava23@gmail.com> | 2024-01-05 18:28:33 +0530 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-01-05 18:28:33 +0530 |
commit | df062d2c788fd76546d59c67452d8d0fe569c533 (patch) | |
tree | b82a837378469c3eb1456aeea40354601b040793 /ext/node/ops/fs.rs | |
parent | bac51f66aa89dd9b79a3c4e844423c3a3399ea13 (diff) |
fix(ext/node): add fs.cp, fs.cpSync, promises.cp (#21745)
Fixes https://github.com/denoland/deno/issues/20803
Fixes https://github.com/denoland/deno/issues/21723
Performance: copying a 48GiB rust `target` folder (recursive)
| Platform | `deno` | `node v21.5` | Improvement |
| -------- | ------- | ------- | ------- |
| macOS (APFS) | 3.1secs | 127.99 secs | **42x** |
| Windows | 18.3secs | 67.2secs | **3.8x** |
Copying files with varying sizes:

Diffstat (limited to 'ext/node/ops/fs.rs')
-rw-r--r-- | ext/node/ops/fs.rs | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/ext/node/ops/fs.rs b/ext/node/ops/fs.rs index 8e4805f6c..c5ae2371e 100644 --- a/ext/node/ops/fs.rs +++ b/ext/node/ops/fs.rs @@ -1,6 +1,9 @@ // Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. +use std::cell::RefCell; +use std::path::Path; use std::path::PathBuf; +use std::rc::Rc; use deno_core::error::AnyError; use deno_core::op2; @@ -24,3 +27,54 @@ where let fs = state.borrow::<FileSystemRc>(); Ok(fs.lstat_sync(&path).is_ok()) } + +#[op2(fast)] +pub fn op_node_cp_sync<P>( + state: &mut OpState, + #[string] path: &str, + #[string] new_path: &str, +) -> Result<(), AnyError> +where + P: NodePermissions + 'static, +{ + let path = Path::new(path); + let new_path = Path::new(new_path); + + state + .borrow_mut::<P>() + .check_read_with_api_name(path, Some("node:fs.cpSync"))?; + state + .borrow_mut::<P>() + .check_write_with_api_name(new_path, Some("node:fs.cpSync"))?; + + let fs = state.borrow::<FileSystemRc>(); + fs.cp_sync(path, new_path)?; + Ok(()) +} + +#[op2(async)] +pub async fn op_node_cp<P>( + state: Rc<RefCell<OpState>>, + #[string] path: String, + #[string] new_path: String, +) -> Result<(), AnyError> +where + P: NodePermissions + 'static, +{ + let path = PathBuf::from(path); + let new_path = PathBuf::from(new_path); + + let fs = { + let mut state = state.borrow_mut(); + state + .borrow_mut::<P>() + .check_read_with_api_name(&path, Some("node:fs.cpSync"))?; + state + .borrow_mut::<P>() + .check_write_with_api_name(&new_path, Some("node:fs.cpSync"))?; + state.borrow::<FileSystemRc>().clone() + }; + + fs.cp_async(path, new_path).await?; + Ok(()) +} |