From 68c89e7547d558a0884e2abf05e5ad301a4a9c8d Mon Sep 17 00:00:00 2001 From: suyanhanx Date: Thu, 6 Apr 2023 22:01:15 +0800 Subject: [PATCH] feat(bindings/nodejs): add `copy` and `rename` Signed-off-by: suyanhanx --- bindings/nodejs/index.d.ts | 52 ++++++++++++++++--- bindings/nodejs/src/lib.rs | 74 ++++++++++++++++++++++++---- core/tests/behavior/blocking_copy.rs | 14 +++--- core/tests/behavior/copy.rs | 14 +++--- core/tests/behavior/rename.rs | 14 +++--- 5 files changed, 131 insertions(+), 37 deletions(-) diff --git a/bindings/nodejs/index.d.ts b/bindings/nodejs/index.d.ts index c3304403bca..1bd46945f10 100644 --- a/bindings/nodejs/index.d.ts +++ b/bindings/nodejs/index.d.ts @@ -111,6 +111,24 @@ export class Operator { * ``` */ createDirSync(path: string): void + /** + * Read the whole path into a buffer. + * + * ### Example + * ```javascript + * const buf = await op.read("path/to/file"); + * ``` + */ + read(path: string): Promise + /** + * Read the whole path into a buffer synchronously. + * + * ### Example + * ```javascript + * const buf = op.readSync("path/to/file"); + * ``` + */ + readSync(path: string): Buffer /** * Write bytes into path. * @@ -134,23 +152,45 @@ export class Operator { */ writeSync(path: string, content: Buffer | string): void /** - * Read the whole path into a buffer. + * Copy file according to given `from` and `to` path. * * ### Example * ```javascript - * const buf = await op.read("path/to/file"); + * await op.copy("path/to/file", "path/to/dest"); * ``` */ - read(path: string): Promise + copy(from: string, to: string): Promise /** - * Read the whole path into a buffer synchronously. + * Copy file according to given `from` and `to` path synchronously. * * ### Example * ```javascript - * const buf = op.readSync("path/to/file"); + * op.copySync("path/to/file", "path/to/dest"); * ``` */ - readSync(path: string): Buffer + copySync(from: string, to: string): void + /** + * Rename file according to given `from` and `to` path. + * + * It's similar to `mv` command. + * + * ### Example + * ```javascript + * await op.rename("path/to/file", "path/to/dest"); + * ``` + */ + rename(from: string, to: string): Promise + /** + * Rename file according to given `from` and `to` path synchronously. + * + * It's similar to `mv` command. + * + * ### Example + * ```javascript + * op.renameSync("path/to/file", "path/to/dest"); + * ``` + */ + renameSync(from: string, to: string): void /** * List dir in flat way. * diff --git a/bindings/nodejs/src/lib.rs b/bindings/nodejs/src/lib.rs index d95c7aa2cb9..bbf831e876d 100644 --- a/bindings/nodejs/src/lib.rs +++ b/bindings/nodejs/src/lib.rs @@ -201,6 +201,30 @@ impl Operator { .map_err(format_napi_error) } + /// Read the whole path into a buffer. + /// + /// ### Example + /// ```javascript + /// const buf = await op.read("path/to/file"); + /// ``` + #[napi] + pub async fn read(&self, path: String) -> Result { + let res = self.0.read(&path).await.map_err(format_napi_error)?; + Ok(res.into()) + } + + /// Read the whole path into a buffer synchronously. + /// + /// ### Example + /// ```javascript + /// const buf = op.readSync("path/to/file"); + /// ``` + #[napi] + pub fn read_sync(&self, path: String) -> Result { + let res = self.0.blocking().read(&path).map_err(format_napi_error)?; + Ok(res.into()) + } + /// Write bytes into path. /// /// ### Example @@ -235,28 +259,58 @@ impl Operator { self.0.blocking().write(&path, c).map_err(format_napi_error) } - /// Read the whole path into a buffer. + /// Copy file according to given `from` and `to` path. /// /// ### Example /// ```javascript - /// const buf = await op.read("path/to/file"); + /// await op.copy("path/to/file", "path/to/dest"); /// ``` #[napi] - pub async fn read(&self, path: String) -> Result { - let res = self.0.read(&path).await.map_err(format_napi_error)?; - Ok(res.into()) + pub async fn copy(&self, from: String, to: String) -> Result<()> { + self.0.copy(&from, &to).await.map_err(format_napi_error) } - /// Read the whole path into a buffer synchronously. + /// Copy file according to given `from` and `to` path synchronously. /// /// ### Example /// ```javascript - /// const buf = op.readSync("path/to/file"); + /// op.copySync("path/to/file", "path/to/dest"); /// ``` #[napi] - pub fn read_sync(&self, path: String) -> Result { - let res = self.0.blocking().read(&path).map_err(format_napi_error)?; - Ok(res.into()) + pub fn copy_sync(&self, from: String, to: String) -> Result<()> { + self.0 + .blocking() + .copy(&from, &to) + .map_err(format_napi_error) + } + + /// Rename file according to given `from` and `to` path. + /// + /// It's similar to `mv` command. + /// + /// ### Example + /// ```javascript + /// await op.rename("path/to/file", "path/to/dest"); + /// ``` + #[napi] + pub async fn rename(&self, from: String, to: String) -> Result<()> { + self.0.rename(&from, &to).await.map_err(format_napi_error) + } + + /// Rename file according to given `from` and `to` path synchronously. + /// + /// It's similar to `mv` command. + /// + /// ### Example + /// ```javascript + /// op.renameSync("path/to/file", "path/to/dest"); + /// ``` + #[napi] + pub fn rename_sync(&self, from: String, to: String) -> Result<()> { + self.0 + .blocking() + .rename(&from, &to) + .map_err(format_napi_error) } /// List dir in flat way. diff --git a/core/tests/behavior/blocking_copy.rs b/core/tests/behavior/blocking_copy.rs index 62cdb0e1b57..583a31fb589 100644 --- a/core/tests/behavior/blocking_copy.rs +++ b/core/tests/behavior/blocking_copy.rs @@ -78,7 +78,7 @@ macro_rules! behavior_blocking_copy_tests { }; } -// Copy a file and test with stat. +/// Copy a file and test with stat. pub fn test_copy(op: BlockingOperator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -97,7 +97,7 @@ pub fn test_copy(op: BlockingOperator) -> Result<()> { Ok(()) } -// Copy a nonexistent source should return an error. +/// Copy a nonexistent source should return an error. pub fn test_copy_non_existing_source(op: BlockingOperator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let target_path = uuid::Uuid::new_v4().to_string(); @@ -109,7 +109,7 @@ pub fn test_copy_non_existing_source(op: BlockingOperator) -> Result<()> { Ok(()) } -// Copy a dir as source should return an error. +/// Copy a dir as source should return an error. pub fn test_copy_source_dir(op: BlockingOperator) -> Result<()> { let source_path = format!("{}/", uuid::Uuid::new_v4()); let target_path = uuid::Uuid::new_v4().to_string(); @@ -123,7 +123,7 @@ pub fn test_copy_source_dir(op: BlockingOperator) -> Result<()> { Ok(()) } -// Copy to a dir should return an error. +/// Copy to a dir should return an error. pub fn test_copy_target_dir(op: BlockingOperator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -144,7 +144,7 @@ pub fn test_copy_target_dir(op: BlockingOperator) -> Result<()> { Ok(()) } -// Copy a file to self should return an error. +/// Copy a file to self should return an error. pub fn test_copy_self(op: BlockingOperator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _size) = gen_bytes(); @@ -160,7 +160,7 @@ pub fn test_copy_self(op: BlockingOperator) -> Result<()> { Ok(()) } -// Copy to a nested path, parent path should be created successfully. +/// Copy to a nested path, parent path should be created successfully. pub fn test_copy_nested(op: BlockingOperator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -179,7 +179,7 @@ pub fn test_copy_nested(op: BlockingOperator) -> Result<()> { Ok(()) } -// Copy to a exist path should overwrite successfully. +/// Copy to a exist path should overwrite successfully. pub fn test_copy_overwrite(op: BlockingOperator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); diff --git a/core/tests/behavior/copy.rs b/core/tests/behavior/copy.rs index af199d227d1..8f0efbec73a 100644 --- a/core/tests/behavior/copy.rs +++ b/core/tests/behavior/copy.rs @@ -77,7 +77,7 @@ macro_rules! behavior_copy_tests { }; } -// Copy a file and test with stat. +/// Copy a file and test with stat. pub async fn test_copy(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -96,7 +96,7 @@ pub async fn test_copy(op: Operator) -> Result<()> { Ok(()) } -// Copy a nonexistent source should return an error. +/// Copy a nonexistent source should return an error. pub async fn test_copy_non_existing_source(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let target_path = uuid::Uuid::new_v4().to_string(); @@ -109,7 +109,7 @@ pub async fn test_copy_non_existing_source(op: Operator) -> Result<()> { Ok(()) } -// Copy a dir as source should return an error. +/// Copy a dir as source should return an error. pub async fn test_copy_source_dir(op: Operator) -> Result<()> { let source_path = format!("{}/", uuid::Uuid::new_v4()); let target_path = uuid::Uuid::new_v4().to_string(); @@ -124,7 +124,7 @@ pub async fn test_copy_source_dir(op: Operator) -> Result<()> { Ok(()) } -// Copy to a dir should return an error. +/// Copy to a dir should return an error. pub async fn test_copy_target_dir(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (content, _) = gen_bytes(); @@ -146,7 +146,7 @@ pub async fn test_copy_target_dir(op: Operator) -> Result<()> { Ok(()) } -// Copy a file to self should return an error. +/// Copy a file to self should return an error. pub async fn test_copy_self(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (content, _) = gen_bytes(); @@ -163,7 +163,7 @@ pub async fn test_copy_self(op: Operator) -> Result<()> { Ok(()) } -// Copy to a nested path, parent path should be created successfully. +/// Copy to a nested path, parent path should be created successfully. pub async fn test_copy_nested(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -182,7 +182,7 @@ pub async fn test_copy_nested(op: Operator) -> Result<()> { Ok(()) } -// Copy to a exist path should overwrite successfully. +/// Copy to a exist path should overwrite successfully. pub async fn test_copy_overwrite(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); diff --git a/core/tests/behavior/rename.rs b/core/tests/behavior/rename.rs index 6fdab267b55..97d1547964c 100644 --- a/core/tests/behavior/rename.rs +++ b/core/tests/behavior/rename.rs @@ -77,7 +77,7 @@ macro_rules! behavior_rename_tests { }; } -// Rename a file and test with stat. +/// Rename a file and test with stat. pub async fn test_rename(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -99,7 +99,7 @@ pub async fn test_rename(op: Operator) -> Result<()> { Ok(()) } -// Rename a nonexistent source should return an error. +/// Rename a nonexistent source should return an error. pub async fn test_rename_non_existing_source(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let target_path = uuid::Uuid::new_v4().to_string(); @@ -112,7 +112,7 @@ pub async fn test_rename_non_existing_source(op: Operator) -> Result<()> { Ok(()) } -// Rename a dir as source should return an error. +/// Rename a dir as source should return an error. pub async fn test_rename_source_dir(op: Operator) -> Result<()> { let source_path = format!("{}/", uuid::Uuid::new_v4()); let target_path = uuid::Uuid::new_v4().to_string(); @@ -127,7 +127,7 @@ pub async fn test_rename_source_dir(op: Operator) -> Result<()> { Ok(()) } -// Rename to a dir should return an error. +/// Rename to a dir should return an error. pub async fn test_rename_target_dir(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (content, _) = gen_bytes(); @@ -149,7 +149,7 @@ pub async fn test_rename_target_dir(op: Operator) -> Result<()> { Ok(()) } -// Rename a file to self should return an error. +/// Rename a file to self should return an error. pub async fn test_rename_self(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (content, _) = gen_bytes(); @@ -166,7 +166,7 @@ pub async fn test_rename_self(op: Operator) -> Result<()> { Ok(()) } -// Rename to a nested path, parent path should be created successfully. +/// Rename to a nested path, parent path should be created successfully. pub async fn test_rename_nested(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes(); @@ -188,7 +188,7 @@ pub async fn test_rename_nested(op: Operator) -> Result<()> { Ok(()) } -// Rename to a exist path should overwrite successfully. +/// Rename to a exist path should overwrite successfully. pub async fn test_rename_overwrite(op: Operator) -> Result<()> { let source_path = uuid::Uuid::new_v4().to_string(); let (source_content, _) = gen_bytes();