Xuanwo commented on code in PR #1861:
URL:
https://github.com/apache/incubator-opendal/pull/1861#discussion_r1159985845
##########
bindings/c/include/opendal.h:
##########
@@ -25,14 +25,229 @@
#include <stddef.h>
#include <stdbool.h>
+/*
+ The C-compatible error type enum used in c bindings.
+ NOTICE: the type definition of [`ErrorNo`] should be aligned with
+ [`od::ErrorKind`]
+ */
+typedef enum opendal_errno {
+ /*
+ returning it back. For example, s3 returns an internal service error.
+ */
+ Unexpected,
+ /*
+ Underlying service doesn't support this operation.
+ */
+ Unsupported,
+ /*
+ The config for backend is invalid.
+ */
+ ConfigInvalid,
+ /*
+ The given path is not found.
+ */
+ NotFound,
+ /*
+ The given path doesn't have enough permission for this operation
+ */
+ PermissionDenied,
+ /*
+ The given path is a directory.
+ */
+ IsADirectory,
+ /*
+ The given path is not a directory.
+ */
+ NotADirectory,
+ /*
+ The given path already exists thus we failed to the specified operation on
it.
+ */
+ AlreadyExists,
+ /*
+ Requests that sent to this path is over the limit, please slow down.
+ */
+ RateLimited,
+ /*
+ The given file paths are same.
+ */
+ IsSameFile,
+ /*
+ Unknown error, since [`opendal::ErrorKind`] is nonexhaustive
+ */
+ UnknownError,
+ /*
+ NullPtr error, meaning that a provided pointer which need to be
dereferenced is null
+ */
+ NullPtr,
+} opendal_errno;
+
+/*
+ The C-compatible error status for opendal::Error.
+ NOTICE: the type definition of [`ErrorNo`] should be aligned with
+ [`od::ErrorStatus`]
+ */
+typedef enum opendal_error_status {
+ /*
+ Permanent means without external changes, the error never changes.
+
+ For example, underlying services returns a not found error.
+
+ Users SHOULD never retry this operation.
+ */
+ Permanent,
+ /*
+ Temporary means this error is returned for temporary.
+
+ For example, underlying services is rate limited or unavailable for
temporary.
+
+ Users CAN retry the operation to resolve it.
+ */
+ Temporary,
+ /*
+ Persistent means this error used to be temporary but still failed after
retry.
+
+ For example, underlying services kept returning network errors.
+
+ Users MAY retry this operation but it's highly possible to error again.
+ */
+ Persistent,
+} opendal_error_status;
+
+/*
+ The [`OperatorPtr`] owns a pointer to a [`od::BlockingOperator`].
+ It is also the key struct that OpenDAL's APIs access the real
+ operator's memory. The use of OperatorPtr is zero cost, it
+ only returns a reference of the underlying Operator.
+
+ The [`OperatorPtr`] also has a transparent layout, allowing you
+ to check its validity by native boolean operator.
+ e.g. you could check by (!ptr) on a opendal_operator_ptr type
+ */
+typedef const void *opendal_operator_ptr;
+
+/*
+ The error type returned of all opendal APIs in the C code
+ */
+typedef struct opendal_error {
+ /*
+ The error number of the actual error
+ */
+ enum opendal_errno errno;
+ /*
+ The error status of the error, please see opendal_error_status
+ for more details
+ */
+ enum opendal_error_status error_status;
+ /*
+ The error_msg consumes an area of heap memory, please call
+ [`opendal_free_error`] on the error to free the memory
+ */
+ const char *error_msg;
+} opendal_error;
+
+/*
+ The Rust-like Result type of opendal C binding, it contains
+ a opendal_operator_ptr and a pointer to an error type.
+ Note that if `error` is not null, the error consumes heap memory
+ remember to free it by using [`opendal_free_error`]
+ */
+typedef struct opendal_result_op {
+ opendal_operator_ptr op_ptr;
+ struct opendal_error *error;
+} opendal_result_op;
+
+/*
+ The Rust-like Result type of opendal C binding, it contains
+ whether the write operation succeeds and a pointer to an error type.
+ Note that if `error` is not null, the error consumes heap memory
+ remember to free it by using [`opendal_free_error`]
+ */
+typedef struct opendal_result_write {
+ bool success;
+ struct opendal_error *error;
+} opendal_result_write;
+
+/*
+ The [`Bytes`] type is a C-compatible substitute for [`Bytes`]
+ in Rust, it will not be deallocated automatically like what
+ has been done in Rust. Instead, you have to call [`opendal_free_bytes`]
+ to free the heap memory to avoid memory leak.
+ The field `data` should not be modified since it might causes
+ the reallocation of the Vector.
+ */
+typedef struct opendal_bytes {
+ const uint8_t *data;
+ uintptr_t len;
+} opendal_bytes;
+
+/*
+ The Rust-like Result type of opendal C binding, it contains
+ the data that the read operation returns and a pointer to an error type.
+ If the read operation failed, the `data` fields should be a nullptr.
+ Note that if `error` is not null, the error consumes heap memory
+ remember to free it by using [`opendal_free_error`]
+ */
+typedef struct opendal_result_read {
+ struct opendal_bytes *data;
+ struct opendal_error *error;
+} opendal_result_read;
+
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
/*
- Hello, OpenDAL!
+ Returns a result type [`opendal_result_op`], with operator_ptr. If the
construction succeeds
+ the error is nullptr, otherwise it contains the error information.
+
+ # Safety
+
+ It is [safe] under two cases below
+ * The memory pointed to by `scheme` must contain a valid nul terminator at
the end of
+ the string.
+ * The `scheme` points to NULL, this function simply returns you a null
opendal_operator_ptr
+ */
+struct opendal_result_op opendal_new_operator(const char *scheme);
+
+/*
+ Write the data into the path blockingly by operator, returns whether the
write succeeds
+ with error type
+
+ # Safety
+
+ It is [safe] under two cases below
+ * The memory pointed to by `path` must contain a valid nul terminator at the
end of
+ the string.
+ * The `path` points to NULL, this function simply returns you false
+ */
+struct opendal_result_write
opendal_operator_blocking_write(opendal_operator_ptr op_ptr,
+ const char *path,
+ struct
opendal_bytes bytes);
+
+/*
+ Read the data out from path into a [`Bytes`] blockingly by operator, returns
+ a result with error type
+
+ # Safety
+
+ It is [safe] under two cases below
+ * The memory pointed to by `path` must contain a valid nul terminator at the
end of
+ the string.
+ * The `path` points to NULL, this function simply returns you a nullptr
+ */
+struct opendal_result_read opendal_operator_blocking_read(opendal_operator_ptr
op_ptr,
+ const char *path);
+
+/*
+ Free the [`CError`] type's heap memory, it is safe to be called
+ on a nullptr
+ */
+void opendal_free_error(struct opendal_error *self);
Review Comment:
> What's your opinion?
I still like `opendal_error_free`. But as discussed in
https://github.com/apache/incubator-opendal/pull/1861#discussion_r1159983964, I
prefer to remove `opendal_error` first.
##########
bindings/c/src/error.rs:
##########
@@ -0,0 +1,203 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements. See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership. The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License. You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied. See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+use std::ffi::CString;
+use std::os::raw::{c_char, c_void};
+
+use ::opendal as od;
+
+/// The wrapper type for opendal's error, wrapped because of the
+/// orphan rule
+pub(crate) struct OpendalError(pub(crate) od::Error);
+
+/// The C-compatible error type enum used in c bindings.
+/// NOTICE: the type definition of [`ErrorNo`] should be aligned with
+/// [`od::ErrorKind`]
+#[repr(C)]
+pub enum opendal_errno {
+ /// returning it back. For example, s3 returns an internal service error.
+ Unexpected,
+ /// Underlying service doesn't support this operation.
+ Unsupported,
+ /// The config for backend is invalid.
+ ConfigInvalid,
+ /// The given path is not found.
+ NotFound,
+ /// The given path doesn't have enough permission for this operation
+ PermissionDenied,
+ /// The given path is a directory.
+ IsADirectory,
+ /// The given path is not a directory.
+ NotADirectory,
+ /// The given path already exists thus we failed to the specified
operation on it.
+ AlreadyExists,
+ /// Requests that sent to this path is over the limit, please slow down.
+ RateLimited,
+ /// The given file paths are same.
+ IsSameFile,
+ /// Unknown error, since [`opendal::ErrorKind`] is nonexhaustive
+ UnknownError,
+ /// NullPtr error, meaning that a provided pointer which need to be
dereferenced is null
+ NullPtr,
Review Comment:
Let's remove this part.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]