diff --git a/Cargo.lock b/Cargo.lock index 8871911..b5deb1d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -115,6 +115,17 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "async-recursion" +version = "1.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "autocfg" version = "1.1.0" @@ -220,6 +231,7 @@ dependencies = [ name = "bueno_ext_fs" version = "0.0.1" dependencies = [ + "async-recursion", "deno_core", "tokio", ] diff --git a/examples/files.ts b/examples/files.ts new file mode 100644 index 0000000..1de8f2d --- /dev/null +++ b/examples/files.ts @@ -0,0 +1,5 @@ +// Bueno.fs.copyFile("./examples/origin.txt", "./examples/dest.txt"); + +// Bueno.fs.copyDirectory("./examples/testOrigin/folder1", "./examples/testDest/folder1"); + +Bueno.fs.moveFolder("./examples/folder1/folder2", "./examples/destFolder/innerDestFolder/renamedFolder"); \ No newline at end of file diff --git a/ext/fs/Cargo.toml b/ext/fs/Cargo.toml index 1c2bc29..cbd0b19 100644 --- a/ext/fs/Cargo.toml +++ b/ext/fs/Cargo.toml @@ -13,3 +13,5 @@ path = "lib.rs" [dependencies] deno_core.workspace = true tokio.workspace = true + +async-recursion = "1.0.5" diff --git a/ext/fs/lib.rs b/ext/fs/lib.rs index cd31ec5..55b0363 100644 --- a/ext/fs/lib.rs +++ b/ext/fs/lib.rs @@ -51,3 +51,66 @@ pub async fn op_remove_dir(#[string] path: String, recursive: bool) -> Result<() Ok(()) } + +#[op2(async)] +pub async fn op_copy_file(#[string] origin: String, #[string] dest: String) -> Result<(), AnyError> { + tokio::fs::copy(origin, dest).await?; + Ok(()) +} + +#[op2(async)] +pub async fn op_copy_dir(#[string] origin: String, #[string] dest: String) -> Result<(), AnyError> { + op_copy_dir_recurse(origin, dest).await?; + Ok(()) +} + +use async_recursion::async_recursion; +#[async_recursion] +pub async fn op_copy_dir_recurse(origin: String, dest: String) -> Result<(), AnyError> { + + // Setup for viewing directory contents and checking if dir + let orgForMetadata = origin.clone(); + let attr = tokio::fs::metadata(orgForMetadata); + let dirBool = attr.await?.is_dir(); + + // if directory, make a directory at destination and loop through contents + if dirBool { + + // Make a new directory at destination + let destForCreate = dest.clone(); + tokio::fs::create_dir(destForCreate).await?; + + // Loop through all contents of folder + let mut entries = tokio::fs::read_dir(origin).await?; + while let Some(entry) = entries.next_entry().await? { + + // Take name of file and add to destination path + let wholePathStr = entry.path().into_os_string().into_string().unwrap().clone(); + let parts = wholePathStr.split("/"); + let itemStr = parts.last().unwrap(); + let mut next = dest.to_owned(); + next.push_str(&"/"); + next.push_str(&itemStr); + + // Recursive call to copy over contents of folder being looked at + op_copy_dir_recurse(entry.path().into_os_string().into_string().unwrap(), next).await?; + } + + // If file, copy file over to destination + } else { + tokio::fs::copy(origin, dest).await?; + } + Ok(()) +} + +#[op2(async)] +pub async fn op_move_file(#[string] origin: String, #[string] dest: String) -> Result<(), AnyError> { + tokio::fs::rename(origin, dest).await?; + Ok(()) +} + +#[op2(async)] +pub async fn op_move_folder(#[string] origin: String, #[string] dest: String) -> Result<(), AnyError> { + tokio::fs::rename(origin, dest).await?; + Ok(()) +} \ No newline at end of file diff --git a/ext/fs/mod.js b/ext/fs/mod.js index 068c081..16a13cf 100644 --- a/ext/fs/mod.js +++ b/ext/fs/mod.js @@ -57,6 +57,46 @@ function removeDirectory(path, recursive) { return core.ops.op_remove_dir(path, recursive); } +/** + * Copies file asynchronously + * @param {string} origin + * @param {string} dest + * @returns {Promise} + */ +function copyFile(origin, dest) { + return core.ops.op_copy_file(origin, dest); +} + +/** + * Copies folder asynchronously + * @param {string} origin + * @param {string} dest + * @returns {Promise} + */ +function copyDirectory(origin, dest) { + return core.ops.op_copy_dir(origin, dest); +} + +/** + * Moves file asyncrhonously + * @param {string} origin + * @param {string} dest + * @returns {Promise} + */ +function moveFile(origin, dest) { + return core.ops.op_move_file(origin, dest); +} + +/** + * Moves folder asyncrhonously + * @param {string} origin + * @param {string} dest + * @returns {Promise} + */ +function moveFolder(origin, dest) { + return core.ops.op_move_folder(origin, dest); +} + Bueno.fs = { readFile, readTextFile, @@ -64,4 +104,8 @@ Bueno.fs = { writeTextFile, removeFile, removeDirectory, + copyFile, + copyDirectory, + moveFile, + moveFolder, }; diff --git a/ext/lib.rs b/ext/lib.rs index 07c2fea..b2dc574 100644 --- a/ext/lib.rs +++ b/ext/lib.rs @@ -23,6 +23,10 @@ pub mod extensions { fs::op_write_text_file, fs::op_remove_file, fs::op_remove_dir, + fs::op_copy_file, + fs::op_copy_dir, + fs::op_move_file, + fs::op_move_folder, performance::op_high_res_time, performance::op_time_origin, timers::op_timers_sleep,