Skip to content

Commit

Permalink
refactor: more consistent C binding pattern
Browse files Browse the repository at this point in the history
Signed-off-by: tison <wander4096@gmail.com>
  • Loading branch information
tisonkun committed Oct 5, 2024
1 parent fa23e1f commit 57b170f
Show file tree
Hide file tree
Showing 9 changed files with 160 additions and 224 deletions.
86 changes: 26 additions & 60 deletions bindings/c/include/opendal.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,60 +81,6 @@ typedef enum opendal_code {
OPENDAL_RANGE_NOT_SATISFIED,
} opendal_code;

/**
* BlockingOperator is the entry for all public blocking APIs.
*
* Read [`concepts`][docs::concepts] for know more about [`Operator`].
*
* # Examples
*
* ## Init backends
*
* Read more backend init examples in [`services`]
*
* ```rust,no_run
* # use anyhow::Result;
* use opendal::services::Fs;
* use opendal::BlockingOperator;
* use opendal::Operator;
*
* fn main() -> Result<()> {
* // Create fs backend builder.
* let builder = Fs::default().root("/tmp");
*
* // Build an `BlockingOperator` to start operating the storage.
* let _: BlockingOperator = Operator::new(builder)?.finish().blocking();
*
* Ok(())
* }
* ```
*
* ## Init backends with blocking layer
*
* Some services like s3, gcs doesn't have native blocking supports, we can use [`layers::BlockingLayer`]
* to wrap the async operator to make it blocking.
* # use anyhow::Result;
* use opendal::layers::BlockingLayer;
* use opendal::services::S3;
* use opendal::BlockingOperator;
* use opendal::Operator;
*
* async fn test() -> Result<()> {
* // Create fs backend builder.
* let mut builder = S3::default().bucket("test").region("us-east-1");
*
* // Build an `BlockingOperator` with blocking layer to start operating the storage.
* let _: BlockingOperator = Operator::new(builder)?
* .layer(BlockingLayer::create()?)
* .finish()
* .blocking();
*
* Ok(())
* }
* ```
*/
typedef struct BlockingOperator BlockingOperator;

/**
* \brief opendal_bytes carries raw-bytes with its length
*
Expand Down Expand Up @@ -188,6 +134,10 @@ typedef struct opendal_error {
* @see opendal_list_entry_name()
*/
typedef struct opendal_entry {
/**
* The pointer to the opendal::Entry in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_entry;

Expand Down Expand Up @@ -219,6 +169,10 @@ typedef struct opendal_result_lister_next {
* @see opendal_operator_list()
*/
typedef struct opendal_lister {
/**
* The pointer to the opendal::BlockingLister in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_lister;

Expand Down Expand Up @@ -259,7 +213,7 @@ typedef struct opendal_operator {
* The pointer to the opendal::BlockingOperator in the Rust code.
* Only touch this on judging whether it is NULL.
*/
const struct BlockingOperator *ptr;
void *inner;
} opendal_operator;

/**
Expand Down Expand Up @@ -297,7 +251,7 @@ typedef struct opendal_result_operator_new {
*/
typedef struct opendal_operator_options {
/**
* The pointer to the Rust HashMap<String, String>
* The pointer to the HashMap<String, String> in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
Expand Down Expand Up @@ -329,6 +283,10 @@ typedef struct opendal_result_read {
* a opendal::BlockingReader, which is inside the Rust core code.
*/
typedef struct opendal_reader {
/**
* The pointer to the opendal::StdReader in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_reader;

Expand All @@ -355,6 +313,10 @@ typedef struct opendal_result_operator_reader {
* an opendal::BlockingWriter, which is inside the Rust core code.
*/
typedef struct opendal_writer {
/**
* The pointer to the opendal::BlockingWriter in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_writer;

Expand Down Expand Up @@ -436,6 +398,10 @@ typedef struct opendal_result_list {
* of operator.
*/
typedef struct opendal_operator_info {
/**
* The pointer to the opendal::OperatorInfo in the Rust code.
* Only touch this on judging whether it is NULL.
*/
void *inner;
} opendal_operator_info;

Expand Down Expand Up @@ -658,7 +624,7 @@ void opendal_error_free(struct opendal_error *ptr);
* For examples, please see the comment section of opendal_operator_list()
* @see opendal_operator_list()
*/
struct opendal_result_lister_next opendal_lister_next(const struct opendal_lister *self);
struct opendal_result_lister_next opendal_lister_next(struct opendal_lister *self);

/**
* \brief Free the heap-allocated metadata used by opendal_lister
Expand Down Expand Up @@ -752,7 +718,7 @@ int64_t opendal_metadata_last_modified_ms(const struct opendal_metadata *self);
* opendal_operator_free(op);
* ```
*/
void opendal_operator_free(const struct opendal_operator *op);
void opendal_operator_free(struct opendal_operator *ptr);

/**
* \brief Construct an operator based on `scheme` and `options`
Expand Down Expand Up @@ -1411,7 +1377,7 @@ void opendal_entry_free(struct opendal_entry *ptr);
/**
* \brief Read data from the reader.
*/
struct opendal_result_reader_read opendal_reader_read(const struct opendal_reader *self,
struct opendal_result_reader_read opendal_reader_read(struct opendal_reader *self,
uint8_t *buf,
uintptr_t len);

Expand All @@ -1423,7 +1389,7 @@ void opendal_reader_free(struct opendal_reader *ptr);
/**
* \brief Write data to the writer.
*/
struct opendal_result_writer_write opendal_writer_write(const struct opendal_writer *self,
struct opendal_result_writer_write opendal_writer_write(struct opendal_writer *self,
struct opendal_bytes bytes);

/**
Expand Down
2 changes: 2 additions & 0 deletions bindings/c/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ use ::opendal as core;
/// @see opendal_list_entry_name()
#[repr(C)]
pub struct opendal_entry {
/// The pointer to the opendal::Entry in the Rust code.
/// Only touch this on judging whether it is NULL.
inner: *mut c_void,
}

Expand Down
4 changes: 3 additions & 1 deletion bindings/c/src/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,9 @@ impl From<core::ErrorKind> for opendal_code {
core::ErrorKind::RangeNotSatisfied => opendal_code::OPENDAL_RANGE_NOT_SATISFIED,
// if this is triggered, check the [`core`] crate and add a
// new error code accordingly
_ => panic!("The newly added ErrorKind in core crate is not handled in C bindings"),
_ => unimplemented!(
"The newly added ErrorKind in core crate is not handled in C bindings"
),
}
}
}
Expand Down
6 changes: 4 additions & 2 deletions bindings/c/src/lister.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ use super::*;
/// @see opendal_operator_list()
#[repr(C)]
pub struct opendal_lister {
/// The pointer to the opendal::BlockingLister in the Rust code.
/// Only touch this on judging whether it is NULL.
inner: *mut c_void,
}

impl opendal_lister {
fn deref_mut(&self) -> &mut core::BlockingLister {
fn deref_mut(&mut self) -> &mut core::BlockingLister {
// Safety: the inner should never be null once constructed
// The use-after-free is undefined behavior
unsafe { &mut *(self.inner as *mut core::BlockingLister) }
Expand All @@ -55,7 +57,7 @@ impl opendal_lister {
/// For examples, please see the comment section of opendal_operator_list()
/// @see opendal_operator_list()
#[no_mangle]
pub unsafe extern "C" fn opendal_lister_next(&self) -> opendal_result_lister_next {
pub unsafe extern "C" fn opendal_lister_next(&mut self) -> opendal_result_lister_next {
let e = self.deref_mut().next();
if e.is_none() {
return opendal_result_lister_next {
Expand Down
Loading

0 comments on commit 57b170f

Please sign in to comment.