This is an automated email from the ASF dual-hosted git repository.

xyji pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 880b648c1 feat(bindings/C): Add opendal_operator_rename and 
opendal_operator_copy (#3517)
880b648c1 is described below

commit 880b648c1ad902698d71768c298dc15b685e9bc2
Author: Enwei Jiao <[email protected]>
AuthorDate: Thu Nov 9 07:35:19 2023 +0800

    feat(bindings/C): Add opendal_operator_rename and opendal_operator_copy 
(#3517)
    
    * Add opendal_operator_rename and opendal_operator_copy for C api
    
    * Add comment
    
    * Regenerate header file
---
 bindings/c/include/opendal.h |  96 +++++++++++++++++++++++++++++++-
 bindings/c/src/operator.rs   | 128 ++++++++++++++++++++++++++++++++++++++++++-
 bindings/c/tests/bdd.cpp     |  20 +++++++
 3 files changed, 242 insertions(+), 2 deletions(-)

diff --git a/bindings/c/include/opendal.h b/bindings/c/include/opendal.h
index 5d9962518..3e17f86dc 100644
--- a/bindings/c/include/opendal.h
+++ b/bindings/c/include/opendal.h
@@ -1119,7 +1119,7 @@ struct opendal_result_stat opendal_operator_stat(const 
struct opendal_operator *
  * lister.
  *
  * @param ptr The opendal_operator created previously
- * @param path The designated path you want to delete
+ * @param path The designated path you want to list
  * @see opendal_lister
  * @return Returns opendal_result_list, containing a lister and an 
opendal_error.
  * If the operation succeeds, the `lister` field would holds a valid lister and
@@ -1202,6 +1202,100 @@ struct opendal_result_list opendal_operator_list(const 
struct opendal_operator *
 struct opendal_error *opendal_operator_create_dir(const struct 
opendal_operator *op,
                                                   const char *path);
 
+/**
+ * \brief Blockingly rename the object in `path`.
+ *
+ * Rename the object in `src` to `dest` blockingly by `op`.
+ * Error is NULL if successful, otherwise it contains the error code and error 
message.
+ *
+ * @param ptr The opendal_operator created previously
+ * @param src The designated source path you want to rename
+ * @param dest The designated destination path you want to rename
+ * @see opendal_operator
+ * @see opendal_error
+ * @return NULL if succeeds, otherwise it contains the error code and error 
message.
+ *
+ * # Example
+ *
+ * Following is an example
+ * ```C
+ * //...prepare your opendal_operator, named ptr for example
+ *
+ * // prepare your data
+ * char* data = "Hello, World!";
+ * opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 };
+ * opendal_error *error = opendal_operator_write(ptr, "/testpath", bytes);
+ *
+ * assert(error == NULL);
+ *
+ * // now you can renmae!
+ * opendal_error *error = opendal_operator_rename(ptr, "/testpath", 
"/testpath2");
+ *
+ * // Assert that this succeeds
+ * assert(error == NULL);
+ * ```
+ *
+ * # Safety
+ *
+ * It is **safe** under the cases below
+ * * The memory pointed to by `path` must contain a valid nul terminator at 
the end of
+ *   the string.
+ *
+ * # Panic
+ *
+ * * If the `src` or `dest` points to NULL, this function panics, i.e. exits 
with information
+ */
+struct opendal_error *opendal_operator_rename(const struct opendal_operator 
*op,
+                                              const char *src,
+                                              const char *dest);
+
+/**
+ * \brief Blockingly copy the object in `path`.
+ *
+ * Copy the object in `src` to `dest` blockingly by `op`.
+ * Error is NULL if successful, otherwise it contains the error code and error 
message.
+ *
+ * @param ptr The opendal_operator created previously
+ * @param src The designated source path you want to copy
+ * @param dest The designated destination path you want to copy
+ * @see opendal_operator
+ * @see opendal_error
+ * @return NULL if succeeds, otherwise it contains the error code and error 
message.
+ *
+ * # Example
+ *
+ * Following is an example
+ * ```C
+ * //...prepare your opendal_operator, named ptr for example
+ *
+ * // prepare your data
+ * char* data = "Hello, World!";
+ * opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 };
+ * opendal_error *error = opendal_operator_write(ptr, "/testpath", bytes);
+ *
+ * assert(error == NULL);
+ *
+ * // now you can renmae!
+ * opendal_error *error = opendal_operator_copy(ptr, "/testpath", 
"/testpath2");
+ *
+ * // Assert that this succeeds
+ * assert(error == NULL);
+ * ```
+ *
+ * # Safety
+ *
+ * It is **safe** under the cases below
+ * * The memory pointed to by `path` must contain a valid nul terminator at 
the end of
+ *   the string.
+ *
+ * # Panic
+ *
+ * * If the `src` or `dest` points to NULL, this function panics, i.e. exits 
with information
+ */
+struct opendal_error *opendal_operator_copy(const struct opendal_operator *op,
+                                            const char *src,
+                                            const char *dest);
+
 /**
  * \brief Get information of underlying accessor.
  *
diff --git a/bindings/c/src/operator.rs b/bindings/c/src/operator.rs
index 2fc102229..7b857f606 100644
--- a/bindings/c/src/operator.rs
+++ b/bindings/c/src/operator.rs
@@ -565,7 +565,7 @@ pub unsafe extern "C" fn opendal_operator_stat(
 /// lister.
 ///
 /// @param ptr The opendal_operator created previously
-/// @param path The designated path you want to delete
+/// @param path The designated path you want to list
 /// @see opendal_lister
 /// @return Returns opendal_result_list, containing a lister and an 
opendal_error.
 /// If the operation succeeds, the `lister` field would holds a valid lister 
and
@@ -678,3 +678,129 @@ pub unsafe extern "C" fn opendal_operator_create_dir(
         Err(e) => opendal_error::new(e),
     }
 }
+
+/// \brief Blockingly rename the object in `path`.
+///
+/// Rename the object in `src` to `dest` blockingly by `op`.
+/// Error is NULL if successful, otherwise it contains the error code and 
error message.
+///
+/// @param ptr The opendal_operator created previously
+/// @param src The designated source path you want to rename
+/// @param dest The designated destination path you want to rename
+/// @see opendal_operator
+/// @see opendal_error
+/// @return NULL if succeeds, otherwise it contains the error code and error 
message.
+///
+/// # Example
+///
+/// Following is an example
+/// ```C
+/// //...prepare your opendal_operator, named ptr for example
+///
+/// // prepare your data
+/// char* data = "Hello, World!";
+/// opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 };
+/// opendal_error *error = opendal_operator_write(ptr, "/testpath", bytes);
+///
+/// assert(error == NULL);
+///
+/// // now you can renmae!
+/// opendal_error *error = opendal_operator_rename(ptr, "/testpath", 
"/testpath2");
+///
+/// // Assert that this succeeds
+/// assert(error == NULL);
+/// ```
+///
+/// # Safety
+///
+/// It is **safe** under the cases below
+/// * The memory pointed to by `path` must contain a valid nul terminator at 
the end of
+///   the string.
+///
+/// # Panic
+///
+/// * If the `src` or `dest` points to NULL, this function panics, i.e. exits 
with information
+#[no_mangle]
+pub unsafe extern "C" fn opendal_operator_rename(
+    op: *const opendal_operator,
+    src: *const c_char,
+    dest: *const c_char,
+) -> *mut opendal_error {
+    if src.is_null() {
+        panic!("The source path given is pointing at NULL");
+    }
+    if dest.is_null() {
+        panic!("The destination path given is pointing at NULL");
+    }
+
+    let op = (*op).as_ref();
+    let src = unsafe { std::ffi::CStr::from_ptr(src).to_str().unwrap() };
+    let dest = unsafe { std::ffi::CStr::from_ptr(dest).to_str().unwrap() };
+    match op.rename(src, dest) {
+        Ok(_) => std::ptr::null_mut(),
+        Err(e) => opendal_error::new(e),
+    }
+}
+
+/// \brief Blockingly copy the object in `path`.
+///
+/// Copy the object in `src` to `dest` blockingly by `op`.
+/// Error is NULL if successful, otherwise it contains the error code and 
error message.
+///
+/// @param ptr The opendal_operator created previously
+/// @param src The designated source path you want to copy
+/// @param dest The designated destination path you want to copy
+/// @see opendal_operator
+/// @see opendal_error
+/// @return NULL if succeeds, otherwise it contains the error code and error 
message.
+///
+/// # Example
+///
+/// Following is an example
+/// ```C
+/// //...prepare your opendal_operator, named ptr for example
+///
+/// // prepare your data
+/// char* data = "Hello, World!";
+/// opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 };
+/// opendal_error *error = opendal_operator_write(ptr, "/testpath", bytes);
+///
+/// assert(error == NULL);
+///
+/// // now you can renmae!
+/// opendal_error *error = opendal_operator_copy(ptr, "/testpath", 
"/testpath2");
+///
+/// // Assert that this succeeds
+/// assert(error == NULL);
+/// ```
+///
+/// # Safety
+///
+/// It is **safe** under the cases below
+/// * The memory pointed to by `path` must contain a valid nul terminator at 
the end of
+///   the string.
+///
+/// # Panic
+///
+/// * If the `src` or `dest` points to NULL, this function panics, i.e. exits 
with information
+#[no_mangle]
+pub unsafe extern "C" fn opendal_operator_copy(
+    op: *const opendal_operator,
+    src: *const c_char,
+    dest: *const c_char,
+) -> *mut opendal_error {
+    if src.is_null() {
+        panic!("The source path given is pointing at NULL");
+    }
+    if dest.is_null() {
+        panic!("The destination path given is pointing at NULL");
+    }
+
+    let op = (*op).as_ref();
+    let src = unsafe { std::ffi::CStr::from_ptr(src).to_str().unwrap() };
+    let dest = unsafe { std::ffi::CStr::from_ptr(dest).to_str().unwrap() };
+    match op.copy(src, dest) {
+        Ok(_) => std::ptr::null_mut(),
+        Err(e) => opendal_error::new(e),
+    }
+}
diff --git a/bindings/c/tests/bdd.cpp b/bindings/c/tests/bdd.cpp
index ee307cc19..1de64da79 100644
--- a/bindings/c/tests/bdd.cpp
+++ b/bindings/c/tests/bdd.cpp
@@ -75,6 +75,26 @@ TEST_F(OpendalBddTest, FeatureTest)
     opendal_metadata* meta = s.meta;
     EXPECT_TRUE(opendal_metadata_is_file(meta));
 
+    // The blocking file "test" should be renamed to "test-copy"
+    error = opendal_operator_rename(this->p, this->path.c_str(), "test-copy");
+    EXPECT_EQ(error, nullptr);
+    e = opendal_operator_is_exist(this->p, "test-copy");
+    EXPECT_EQ(e.error, nullptr);
+    EXPECT_TRUE(e.is_exist);
+    e = opendal_operator_is_exist(this->p, this->path.c_str());
+    EXPECT_EQ(e.error, nullptr);
+    EXPECT_FALSE(e.is_exist);
+
+    // The blocking file "test-copy" should be copied to "test"
+    error = opendal_operator_copy(this->p, "test-copy", this->path.c_str());
+    EXPECT_EQ(error, nullptr);
+    e = opendal_operator_is_exist(this->p, this->path.c_str());
+    EXPECT_EQ(e.error, nullptr);
+    EXPECT_TRUE(e.is_exist);
+    e = opendal_operator_is_exist(this->p, "test-copy");
+    EXPECT_EQ(e.error, nullptr);
+    EXPECT_TRUE(e.is_exist);
+
     // The blocking file "test" content length must be 13
     EXPECT_EQ(opendal_metadata_content_length(meta), 13);
 

Reply via email to