blob: 9568246cf1ea422c8b9eafe695fc0afad28e8af2 [file]
// 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::c_void;
use crate::byte_buffer::{ByteBuffer, buffer_free};
use crate::entry::entry_list_free;
use crate::error::OpenDALError;
use crate::metadata::metadata_free;
use crate::operator::operator_info_free;
use crate::presign::presigned_request_free;
#[repr(C)]
/// Result for operations that only report success or failure.
pub struct OpendalResult {
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning an operator handle pointer.
pub struct OpendalOperatorResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning an options handle pointer.
pub struct OpendalOptionsResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning an executor handle pointer.
pub struct OpendalExecutorResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning an operator info payload pointer.
pub struct OpendalOperatorInfoResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning a metadata payload pointer.
pub struct OpendalMetadataResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning an entry list payload pointer.
pub struct OpendalEntryListResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning a byte buffer payload.
pub struct OpendalReadResult {
pub buffer: ByteBuffer,
pub error: OpenDALError,
}
#[repr(C)]
/// Result for operations returning a presigned request payload pointer.
pub struct OpendalPresignedRequestResult {
pub ptr: *mut c_void,
pub error: OpenDALError,
}
macro_rules! define_result {
($result_ty:ident) => {
impl $result_ty {
pub fn ok() -> Self {
Self {
error: OpenDALError::ok(),
}
}
pub fn from_error(error: OpenDALError) -> Self {
Self { error }
}
}
};
(
$result_ty:ident,
field = $field:ident : $payload_ty:ty,
error_value = $error_value:expr
) => {
impl $result_ty {
pub fn ok($field: $payload_ty) -> Self {
Self {
$field,
error: OpenDALError::ok(),
}
}
pub fn from_error(error: OpenDALError) -> Self {
Self {
$field: $error_value,
error,
}
}
}
};
}
define_result!(OpendalResult);
define_result!(
OpendalOperatorResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
define_result!(
OpendalOptionsResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
define_result!(
OpendalExecutorResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
define_result!(
OpendalOperatorInfoResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
define_result!(
OpendalMetadataResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
define_result!(
OpendalEntryListResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
define_result!(
OpendalReadResult,
field = buffer: ByteBuffer,
error_value = ByteBuffer::empty()
);
define_result!(
OpendalPresignedRequestResult,
field = ptr: *mut c_void,
error_value = std::ptr::null_mut()
);
fn release_error_message(error: &mut OpenDALError) {
if error.message.is_null() {
return;
}
unsafe {
drop(std::ffi::CString::from_raw(error.message));
}
error.message = std::ptr::null_mut();
}
/// Release an error message allocated by this FFI layer.
///
/// This function only releases `OpenDALError.message` and does not touch any
/// payload pointer carried by result structs.
#[unsafe(no_mangle)]
pub extern "C" fn opendal_error_release(mut error: OpenDALError) {
release_error_message(&mut error);
}
/// Release an operator-info result payload and its error message.
///
/// This function is idempotent for null payload pointers.
/// # Safety
///
/// - `result.ptr`, when non-null, must come from `operator_info_get`.
/// - The payload pointer must not be used after this call.
#[unsafe(no_mangle)]
pub extern "C" fn opendal_operator_info_result_release(mut result: OpendalOperatorInfoResult) {
if !result.ptr.is_null() {
unsafe {
operator_info_free(result.ptr.cast());
}
}
release_error_message(&mut result.error);
}
/// Release a metadata result payload and its error message.
///
/// This function is idempotent for null payload pointers.
/// # Safety
///
/// - `result.ptr`, when non-null, must come from metadata-producing APIs in
/// this crate.
/// - The payload pointer must not be used after this call.
#[unsafe(no_mangle)]
pub extern "C" fn opendal_metadata_result_release(mut result: OpendalMetadataResult) {
if !result.ptr.is_null() {
unsafe {
metadata_free(result.ptr.cast());
}
}
release_error_message(&mut result.error);
}
/// Release an entry-list result payload and its error message.
///
/// This function is idempotent for null payload pointers.
/// # Safety
///
/// - `result.ptr`, when non-null, must come from list-producing APIs in this
/// crate.
/// - The payload pointer must not be used after this call.
#[unsafe(no_mangle)]
pub extern "C" fn opendal_entry_list_result_release(mut result: OpendalEntryListResult) {
if !result.ptr.is_null() {
unsafe {
entry_list_free(result.ptr.cast());
}
}
release_error_message(&mut result.error);
}
/// Release a read result buffer and its error message.
///
/// This function is idempotent for empty/null buffers.
/// # Safety
///
/// - `result.buffer` must originate from `ByteBuffer::from_vec` in this crate.
/// - The buffer memory must not be accessed after this call.
#[unsafe(no_mangle)]
pub extern "C" fn opendal_read_result_release(mut result: OpendalReadResult) {
if !result.buffer.data.is_null() {
unsafe {
buffer_free(
result.buffer.data,
result.buffer.len,
result.buffer.capacity,
);
}
}
release_error_message(&mut result.error);
}
/// Release a presigned-request result payload and its error message.
///
/// This function is idempotent for null payload pointers.
/// # Safety
///
/// - `result.ptr`, when non-null, must come from presign-producing APIs in
/// this crate.
/// - The payload pointer must not be used after this call.
#[unsafe(no_mangle)]
pub extern "C" fn opendal_presigned_request_result_release(
mut result: OpendalPresignedRequestResult,
) {
if !result.ptr.is_null() {
unsafe {
presigned_request_free(result.ptr.cast());
}
}
release_error_message(&mut result.error);
}