diff --git a/bindings/c/include/opendal.h b/bindings/c/include/opendal.h index c45434d4ea27..d535e6dcf768 100644 --- a/bindings/c/include/opendal.h +++ b/bindings/c/include/opendal.h @@ -401,6 +401,49 @@ enum opendal_code opendal_operator_blocking_write(struct opendal_operator_ptr pt struct opendal_result_read opendal_operator_blocking_read(struct opendal_operator_ptr ptr, const char *path); +/** + * \brief Blockingly delete the object in `path`. + * + * Delete the object in `path` blockingly by `op_ptr`, returns the opendal_code OPENDAL_OK + * if succeeds, others otherwise + * + * @param ptr The opendal_operator_ptr created previously + * @param path The designated path you want to delete + * @see opendal_operator_ptr + * @see opendal_code + * @return OPENDAL_OK if succeeds others otherwise + * + * # Example + * + * Following is an example + * ```C + * //...prepare your opendal_operator_ptr, named ptr for example + * + * // prepare your data + * char* data = "Hello, World!"; + * opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 }; + * opendal_code code = opendal_operator_blocking_write(ptr, "/testpath", bytes); + * + * // now you can delete! + * opendal_code code = opendal_operator_blocking_delete(ptr, "/testpath"); + * + * // Assert that this succeeds + * assert(code == OPENDAL_OK) + * ``` + * + * # 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 `path` points to NULL, this function panics, i.e. exits with information + */ +enum opendal_code opendal_operator_blocking_delete(struct opendal_operator_ptr ptr, + const char *path); + /** * \brief Check whether the path exists. * diff --git a/bindings/c/src/lib.rs b/bindings/c/src/lib.rs index f380fb15ba3a..4089f96a8944 100644 --- a/bindings/c/src/lib.rs +++ b/bindings/c/src/lib.rs @@ -235,6 +235,61 @@ pub unsafe extern "C" fn opendal_operator_blocking_read( } } +/// \brief Blockingly delete the object in `path`. +/// +/// Delete the object in `path` blockingly by `op_ptr`, returns the opendal_code OPENDAL_OK +/// if succeeds, others otherwise +/// +/// @param ptr The opendal_operator_ptr created previously +/// @param path The designated path you want to delete +/// @see opendal_operator_ptr +/// @see opendal_code +/// @return OPENDAL_OK if succeeds others otherwise +/// +/// # Example +/// +/// Following is an example +/// ```C +/// //...prepare your opendal_operator_ptr, named ptr for example +/// +/// // prepare your data +/// char* data = "Hello, World!"; +/// opendal_bytes bytes = opendal_bytes { .data = (uint8_t*)data, .len = 13 }; +/// opendal_code code = opendal_operator_blocking_write(ptr, "/testpath", bytes); +/// +/// // now you can delete! +/// opendal_code code = opendal_operator_blocking_delete(ptr, "/testpath"); +/// +/// // Assert that this succeeds +/// assert(code == OPENDAL_OK) +/// ``` +/// +/// # 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 `path` points to NULL, this function panics, i.e. exits with information +#[no_mangle] +pub unsafe extern "C" fn opendal_operator_blocking_delete( + ptr: opendal_operator_ptr, + path: *const c_char, +) -> opendal_code { + if path.is_null() { + panic!("The path given is pointing at NULL"); + } + + let op = ptr.as_ref(); + let path = unsafe { std::ffi::CStr::from_ptr(path).to_str().unwrap() }; + match op.delete(path) { + Ok(_) => opendal_code::OPENDAL_OK, + Err(e) => opendal_code::from_opendal_error(e), + } +} + /// \brief Check whether the path exists. /// /// If the operation succeeds, no matter the path exists or not, diff --git a/bindings/c/tests/bdd.cpp b/bindings/c/tests/bdd.cpp index 2b8c2f01f600..4904259581c5 100644 --- a/bindings/c/tests/bdd.cpp +++ b/bindings/c/tests/bdd.cpp @@ -82,6 +82,18 @@ TEST_F(OpendalBddTest, FeatureTest) for (int i = 0; i < r.data->len; i++) { EXPECT_EQ(this->content[i], (char)(r.data->data[i])); } + + // The blocking file should be deleted + code = opendal_operator_blocking_delete(this->p, this->path.c_str()); + EXPECT_EQ(code, OPENDAL_OK); + e = opendal_operator_is_exist(this->p, this->path.c_str()); + EXPECT_EQ(e.code, OPENDAL_OK); + EXPECT_FALSE(e.is_exist); + + // The deletion operation should be idempotent + code = opendal_operator_blocking_delete(this->p, this->path.c_str()); + EXPECT_EQ(code, OPENDAL_OK); + opendal_bytes_free(r.data); }