///|
/// Native operator storage is a MoonBit external object finalized by the C
/// stub. Its payload contains only project-owned C ABI handles.
pub type Operator
///|
/// Capability is an immutable external snapshot of the ABI capability words.
pub type Capability
///|
/// Native lister storage is a MoonBit external object finalized by the C stub.
priv type NativeLister
///|
/// Native random-access reader storage finalized by the C stub.
priv type NativeReader
///|
/// Native sequential read-stream storage finalized by the C stub.
priv type NativeReadStream
///|
/// Native chunked writer storage finalized by the C stub without finishing.
priv type NativeWriter
///|
/// Native same-Operator copier storage finalized by the C stub without
/// finishing or aborting the copy implicitly.
priv type NativeCopier
///|
/// Temporary owned native entry snapshot.
priv type NativeEntry
///|
/// Safe lister wrapper retaining the prefix used for error context.
pub struct Lister {
priv native : NativeLister
priv path : String
}
///|
/// Safe random-access reader retaining the path used for error context.
pub struct Reader {
priv native : NativeReader
priv path : String
}
///|
/// Safe chunked writer retaining the path used for error context.
pub struct Writer {
priv native : NativeWriter
priv path : String
}
///|
/// Call-scoped native result. The C finalizer releases every untaken Rust
/// handle, snapshot, error, or buffer.
priv type NativeResult
///|
/// Temporary Rust metadata snapshot owned through a MoonBit external object.
priv type NativeMetadata
///|
/// Temporary owned native presigned-request snapshot.
priv type NativePresignedRequest
///|
#borrow(scheme, keys, values)
extern "C" fn native_operator_new(
scheme : String,
keys : FixedArray[String],
values : FixedArray[String],
) -> NativeResult = "moonbit_opendal_operator_new"
///|
#borrow(operator)
extern "C" fn native_operator_close(operator : Operator) -> Unit = "moonbit_opendal_operator_close"
///|
#borrow(bucket, region, root, endpoint, access_key_id, secret_access_key, session_token, role_arn, external_id, role_session_name)
extern "C" fn native_operator_s3(
bucket : String,
region : String,
has_root : Bool,
root : String,
has_endpoint : Bool,
endpoint : String,
auth_kind : UInt,
source_kind : UInt,
disable_ec2_metadata : Bool,
access_key_id : String,
secret_access_key : String,
has_session_token : Bool,
session_token : String,
role_arn : String,
has_external_id : Bool,
external_id : String,
has_role_session_name : Bool,
role_session_name : String,
has_duration_seconds : Bool,
duration_seconds : UInt,
virtual_host_style : Bool,
) -> NativeResult = "moonbit_opendal_operator_s3"
///|
#borrow(operator)
extern "C" fn native_operator_with_timeout(
operator : Operator,
operation_timeout_millis : UInt64,
io_timeout_millis : UInt64,
) -> NativeResult = "moonbit_opendal_operator_with_timeout"
///|
#borrow(operator)
extern "C" fn native_operator_with_retry(
operator : Operator,
max_retries : UInt,
min_delay_millis : UInt64,
max_delay_millis : UInt64,
jitter : Bool,
) -> NativeResult = "moonbit_opendal_operator_with_retry"
///|
#borrow(operator)
extern "C" fn native_operator_with_concurrency_limit(
operator : Operator,
operation_limit : UInt64,
has_http_request_limit : Bool,
http_request_limit : UInt64,
) -> NativeResult = "moonbit_opendal_operator_with_concurrency_limit"
///|
#borrow(operator)
extern "C" fn native_operator_check(operator : Operator) -> NativeResult = "moonbit_opendal_operator_check"
///|
#borrow(operator, path)
extern "C" fn native_operator_exists(
operator : Operator,
path : String,
) -> NativeResult = "moonbit_opendal_operator_exists"
///|
#borrow(operator, path, version, if_match, if_none_match)
extern "C" fn native_operator_stat(
operator : Operator,
path : String,
has_version : Bool,
version : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_stat"
///|
#borrow(operator, path, version, if_match, if_none_match)
extern "C" fn native_operator_presign_stat(
operator : Operator,
path : String,
expires_in_seconds : UInt64,
has_version : Bool,
version : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_presign_stat"
///|
#borrow(operator, path, version, if_match, if_none_match)
extern "C" fn native_operator_read(
operator : Operator,
path : String,
range_kind : UInt,
range_offset : UInt64,
range_length : UInt64,
has_version : Bool,
version : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_read"
///|
#borrow(operator, path, version, if_match, if_none_match)
extern "C" fn native_operator_presign_read(
operator : Operator,
path : String,
expires_in_seconds : UInt64,
range_kind : UInt,
range_offset : UInt64,
range_length : UInt64,
has_version : Bool,
version : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_presign_read"
///|
#borrow(operator, path, version, if_match, if_none_match)
extern "C" fn native_operator_reader(
operator : Operator,
path : String,
has_version : Bool,
version : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_reader"
///|
#borrow(reader)
extern "C" fn native_reader_read(
reader : NativeReader,
range_kind : UInt,
range_offset : UInt64,
range_length : UInt64,
) -> NativeResult = "moonbit_opendal_reader_read"
///|
#borrow(reader)
extern "C" fn native_reader_close(reader : NativeReader) -> Unit = "moonbit_opendal_reader_close"
///|
#borrow(operator, path, version, if_match, if_none_match)
extern "C" fn native_operator_read_stream(
operator : Operator,
path : String,
range_kind : UInt,
range_offset : UInt64,
range_length : UInt64,
chunk_size : Int,
has_version : Bool,
version : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_read_stream"
///|
#borrow(stream)
extern "C" fn native_read_stream_next(
stream : NativeReadStream,
) -> NativeResult = "moonbit_opendal_read_stream_next"
///|
#borrow(stream)
extern "C" fn native_read_stream_close(stream : NativeReadStream) -> Unit = "moonbit_opendal_read_stream_close"
///|
#borrow(operator, path, data, content_type, content_disposition, content_encoding, cache_control, if_match, if_none_match)
extern "C" fn native_operator_write(
operator : Operator,
path : String,
data : Bytes,
append : Bool,
has_content_type : Bool,
content_type : String,
has_content_disposition : Bool,
content_disposition : String,
has_content_encoding : Bool,
content_encoding : String,
has_cache_control : Bool,
cache_control : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_write"
///|
#borrow(operator, path, content_type, content_disposition, content_encoding, cache_control, if_match, if_none_match)
extern "C" fn native_operator_presign_write(
operator : Operator,
path : String,
expires_in_seconds : UInt64,
append : Bool,
has_content_type : Bool,
content_type : String,
has_content_disposition : Bool,
content_disposition : String,
has_content_encoding : Bool,
content_encoding : String,
has_cache_control : Bool,
cache_control : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_presign_write"
///|
#borrow(operator, path, content_type, content_disposition, content_encoding, cache_control, if_match, if_none_match)
extern "C" fn native_operator_writer(
operator : Operator,
path : String,
append : Bool,
has_content_type : Bool,
content_type : String,
has_content_disposition : Bool,
content_disposition : String,
has_content_encoding : Bool,
content_encoding : String,
has_cache_control : Bool,
cache_control : String,
has_if_match : Bool,
if_match : String,
has_if_none_match : Bool,
if_none_match : String,
) -> NativeResult = "moonbit_opendal_operator_writer"
///|
#borrow(writer, data)
extern "C" fn native_writer_write(
writer : NativeWriter,
data : Bytes,
) -> NativeResult = "moonbit_opendal_writer_write"
///|
#borrow(writer)
extern "C" fn native_writer_close(writer : NativeWriter) -> NativeResult = "moonbit_opendal_writer_close"
///|
#borrow(writer)
extern "C" fn native_writer_abort(writer : NativeWriter) -> NativeResult = "moonbit_opendal_writer_abort"
///|
#borrow(operator, source, destination)
extern "C" fn native_operator_copy(
operator : Operator,
source : String,
destination : String,
) -> NativeResult = "moonbit_opendal_operator_copy"
///|
#borrow(operator, source, destination)
extern "C" fn native_operator_rename(
operator : Operator,
source : String,
destination : String,
) -> NativeResult = "moonbit_opendal_operator_rename"
///|
#borrow(operator, path)
extern "C" fn native_operator_create_dir(
operator : Operator,
path : String,
) -> NativeResult = "moonbit_opendal_operator_create_dir"
///|
#borrow(operator, path, version)
extern "C" fn native_operator_delete(
operator : Operator,
path : String,
has_version : Bool,
version : String,
recursive : Bool,
) -> NativeResult = "moonbit_opendal_operator_delete"
///|
#borrow(operator, paths)
extern "C" fn native_operator_delete_many(
operator : Operator,
paths : FixedArray[String],
) -> NativeResult = "moonbit_opendal_operator_delete_many"
///|
#borrow(operator, source, destination)
extern "C" fn native_operator_copier(
operator : Operator,
source : String,
destination : String,
) -> NativeResult = "moonbit_opendal_operator_copier"
///|
#borrow(copier)
extern "C" fn native_copier_next(copier : NativeCopier) -> NativeResult = "moonbit_opendal_copier_next"
///|
#borrow(copier)
extern "C" fn native_copier_finish(copier : NativeCopier) -> NativeResult = "moonbit_opendal_copier_finish"
///|
#borrow(copier)
extern "C" fn native_copier_abort(copier : NativeCopier) -> NativeResult = "moonbit_opendal_copier_abort"
///|
#borrow(operator, path, start_after)
extern "C" fn native_operator_lister(
operator : Operator,
path : String,
recursive : Bool,
has_limit : Bool,
limit : UInt64,
has_start_after : Bool,
start_after : String,
) -> NativeResult = "moonbit_opendal_operator_lister"
///|
#borrow(lister)
extern "C" fn native_lister_next(lister : NativeLister) -> NativeResult = "moonbit_opendal_lister_next"
///|
#borrow(lister)
extern "C" fn native_lister_close(lister : NativeLister) -> Unit = "moonbit_opendal_lister_close"
///|
#borrow(result)
extern "C" fn native_result_status(result : NativeResult) -> UInt = "moonbit_opendal_result_status"
///|
#borrow(result)
extern "C" fn native_result_error_kind(result : NativeResult) -> UInt = "moonbit_opendal_result_error_kind"
///|
#borrow(result)
extern "C" fn native_result_error_status(result : NativeResult) -> UInt = "moonbit_opendal_result_error_status"
///|
#borrow(result)
extern "C" fn native_result_error_kind_name(result : NativeResult) -> Bytes = "moonbit_opendal_result_error_kind_name"
///|
#borrow(result)
extern "C" fn native_result_error_message(result : NativeResult) -> Bytes = "moonbit_opendal_result_error_message"
///|
#borrow(result)
extern "C" fn native_result_take_operator(result : NativeResult) -> Operator = "moonbit_opendal_result_take_operator"
///|
#borrow(result)
extern "C" fn native_result_take_lister(result : NativeResult) -> NativeLister = "moonbit_opendal_result_take_lister"
///|
#borrow(result)
extern "C" fn native_result_take_reader(result : NativeResult) -> NativeReader = "moonbit_opendal_result_take_reader"
///|
#borrow(result)
extern "C" fn native_result_take_read_stream(
result : NativeResult,
) -> NativeReadStream = "moonbit_opendal_result_take_read_stream"
///|
#borrow(result)
extern "C" fn native_result_take_writer(result : NativeResult) -> NativeWriter = "moonbit_opendal_result_take_writer"
///|
#borrow(result)
extern "C" fn native_result_take_copier(result : NativeResult) -> NativeCopier = "moonbit_opendal_result_take_copier"
///|
#borrow(result)
extern "C" fn native_result_take_entry(result : NativeResult) -> NativeEntry = "moonbit_opendal_result_take_entry"
///|
#borrow(result)
extern "C" fn native_result_take_bool(result : NativeResult) -> Bool = "moonbit_opendal_result_take_bool"
///|
#borrow(result)
extern "C" fn native_result_take_uint64(result : NativeResult) -> UInt64 = "moonbit_opendal_result_take_uint64"
///|
#borrow(result)
extern "C" fn native_result_take_bytes(result : NativeResult) -> Bytes = "moonbit_opendal_result_take_bytes"
///|
#borrow(result)
extern "C" fn native_result_take_metadata(
result : NativeResult,
) -> NativeMetadata = "moonbit_opendal_result_take_metadata"
///|
#borrow(result)
extern "C" fn native_result_take_presigned_request(
result : NativeResult,
) -> NativePresignedRequest = "moonbit_opendal_result_take_presigned_request"
///|
#borrow(result)
extern "C" fn native_result_release(result : NativeResult) -> Unit = "moonbit_opendal_result_release"
///|
#borrow(entry)
extern "C" fn native_entry_path(entry : NativeEntry) -> Bytes = "moonbit_opendal_entry_path"
///|
#borrow(entry)
extern "C" fn native_entry_name(entry : NativeEntry) -> Bytes = "moonbit_opendal_entry_name"
///|
#borrow(entry)
extern "C" fn native_entry_take_metadata(entry : NativeEntry) -> NativeMetadata = "moonbit_opendal_entry_take_metadata"
///|
#borrow(entry)
extern "C" fn native_entry_release(entry : NativeEntry) -> Unit = "moonbit_opendal_entry_release"
///|
#borrow(operator)
extern "C" fn native_operator_info_scheme(operator : Operator) -> Bytes = "moonbit_opendal_operator_info_scheme"
///|
#borrow(operator)
extern "C" fn native_operator_info_root(operator : Operator) -> Bytes = "moonbit_opendal_operator_info_root"
///|
#borrow(operator)
extern "C" fn native_operator_info_name(operator : Operator) -> Bytes = "moonbit_opendal_operator_info_name"
///|
#borrow(operator)
extern "C" fn native_operator_info_capability(
operator : Operator,
) -> Capability = "moonbit_opendal_operator_info_capability"
///|
#borrow(capability)
extern "C" fn native_capability_word(
capability : Capability,
index : Int,
) -> UInt64 = "moonbit_opendal_capability_word"
///|
#borrow(metadata)
extern "C" fn native_metadata_present_bits(metadata : NativeMetadata) -> UInt64 = "moonbit_opendal_metadata_present_bits"
///|
#borrow(metadata)
extern "C" fn native_metadata_mode(metadata : NativeMetadata) -> UInt = "moonbit_opendal_metadata_mode"
///|
#borrow(metadata)
extern "C" fn native_metadata_content_length(
metadata : NativeMetadata,
) -> UInt64 = "moonbit_opendal_metadata_content_length"
///|
#borrow(metadata)
extern "C" fn native_metadata_is_current(metadata : NativeMetadata) -> Bool = "moonbit_opendal_metadata_is_current"
///|
#borrow(metadata)
extern "C" fn native_metadata_is_deleted(metadata : NativeMetadata) -> Bool = "moonbit_opendal_metadata_is_deleted"
///|
#borrow(metadata)
extern "C" fn native_metadata_last_modified_seconds(
metadata : NativeMetadata,
) -> Int64 = "moonbit_opendal_metadata_last_modified_seconds"
///|
#borrow(metadata)
extern "C" fn native_metadata_last_modified_nanoseconds(
metadata : NativeMetadata,
) -> UInt = "moonbit_opendal_metadata_last_modified_nanoseconds"
///|
#borrow(metadata)
extern "C" fn native_metadata_cache_control(metadata : NativeMetadata) -> Bytes = "moonbit_opendal_metadata_cache_control"
///|
#borrow(metadata)
extern "C" fn native_metadata_content_disposition(
metadata : NativeMetadata,
) -> Bytes = "moonbit_opendal_metadata_content_disposition"
///|
#borrow(metadata)
extern "C" fn native_metadata_content_encoding(
metadata : NativeMetadata,
) -> Bytes = "moonbit_opendal_metadata_content_encoding"
///|
#borrow(metadata)
extern "C" fn native_metadata_content_md5(metadata : NativeMetadata) -> Bytes = "moonbit_opendal_metadata_content_md5"
///|
#borrow(metadata)
extern "C" fn native_metadata_content_type(metadata : NativeMetadata) -> Bytes = "moonbit_opendal_metadata_content_type"
///|
#borrow(metadata)
extern "C" fn native_metadata_etag(metadata : NativeMetadata) -> Bytes = "moonbit_opendal_metadata_etag"
///|
#borrow(metadata)
extern "C" fn native_metadata_version(metadata : NativeMetadata) -> Bytes = "moonbit_opendal_metadata_version"
///|
#borrow(metadata)
extern "C" fn native_metadata_release(metadata : NativeMetadata) -> Unit = "moonbit_opendal_metadata_release"
///|
#borrow(request)
extern "C" fn native_presigned_request_method(
request : NativePresignedRequest,
) -> Bytes = "moonbit_opendal_presigned_request_method"
///|
#borrow(request)
extern "C" fn native_presigned_request_uri(
request : NativePresignedRequest,
) -> Bytes = "moonbit_opendal_presigned_request_uri"
///|
#borrow(request)
extern "C" fn native_presigned_request_header_count(
request : NativePresignedRequest,
) -> UInt64 = "moonbit_opendal_presigned_request_header_count"
///|
#borrow(request)
extern "C" fn native_presigned_request_header_name(
request : NativePresignedRequest,
index : Int,
) -> Bytes = "moonbit_opendal_presigned_request_header_name"
///|
#borrow(request)
extern "C" fn native_presigned_request_header_value(
request : NativePresignedRequest,
index : Int,
) -> Bytes = "moonbit_opendal_presigned_request_header_value"
///|
#borrow(request)
extern "C" fn native_presigned_request_release(
request : NativePresignedRequest,
) -> Unit = "moonbit_opendal_presigned_request_release"
///|
fn abi_text_error(
operation : Operation,
path : String?,
destination_path : String?,
) -> OpenDalError {
OpenDalError({
kind: AbiMismatch,
status: Permanent,
message: "native ABI returned malformed UTF-8",
operation,
path,
destination_path,
})
}
///|
fn decode_abi_text(
bytes : Bytes,
operation : Operation,
path : String?,
destination_path : String?,
) -> String raise OpenDalError {
try @utf8.decode(bytes) catch {
_ => raise abi_text_error(operation, path, destination_path)
} noraise {
text => text
}
}
///|
fn binding_error(
kind : ErrorKind,
operation : Operation,
message : String,
path : String?,
destination_path : String?,
) -> OpenDalError {
OpenDalError({
kind,
status: Permanent,
message,
operation,
path,
destination_path,
})
}
///|
fn native_error_kind(code : UInt, name : String) -> ErrorKind {
match code {
1U => Unexpected
2U => Unsupported
3U => ConfigInvalid
4U => NotFound
5U => PermissionDenied
6U => IsADirectory
7U => NotADirectory
8U => AlreadyExists
9U => RateLimited
10U => IsSameFile
11U => ConditionNotMatch
12U => RangeNotSatisfied
0x1001U => InvalidArgument
0x1002U => ResourceClosed
0x1003U => BufferTooLarge
0x1004U => AbiMismatch
other => UnknownKind(other.reinterpret_as_int(), name)
}
}
///|
fn native_error_status(code : UInt) -> ErrorStatus {
match code {
1U => Permanent
2U => Temporary
3U => Persistent
other => UnknownStatus(other.reinterpret_as_int())
}
}
///|
fn error_from_native_result(
result : NativeResult,
operation : Operation,
path : String?,
destination_path : String?,
) -> OpenDalError raise OpenDalError {
let kind_code = native_result_error_kind(result)
let status_code = native_result_error_status(result)
let kind_name_bytes = native_result_error_kind_name(result)
let message_bytes = native_result_error_message(result)
native_result_release(result)
let kind_name = decode_abi_text(
kind_name_bytes, operation, path, destination_path,
)
let message = decode_abi_text(
message_bytes, operation, path, destination_path,
)
OpenDalError({
kind: native_error_kind(kind_code, kind_name),
status: native_error_status(status_code),
message,
operation,
path,
destination_path,
})
}
///|
fn metadata_bit(bits : UInt64, index : Int) -> Bool {
(bits & (1UL << index)) != 0UL
}
///|
fn optional_metadata_text(
present : Bool,
bytes : Bytes,
operation : Operation,
path : String?,
destination_path : String?,
) -> String? raise OpenDalError {
if present {
Some(decode_abi_text(bytes, operation, path, destination_path))
} else {
None
}
}
///|
fn metadata_from_native(
metadata : NativeMetadata,
operation : Operation,
path : String?,
destination_path? : String,
) -> Metadata raise OpenDalError {
let bits = native_metadata_present_bits(metadata)
let mode_code = native_metadata_mode(metadata)
let content_length = native_metadata_content_length(metadata)
let is_current_value = native_metadata_is_current(metadata)
let is_deleted = native_metadata_is_deleted(metadata)
let modified_seconds = native_metadata_last_modified_seconds(metadata)
let modified_nanoseconds = native_metadata_last_modified_nanoseconds(metadata)
let cache_control_bytes = native_metadata_cache_control(metadata)
let content_disposition_bytes = native_metadata_content_disposition(metadata)
let content_encoding_bytes = native_metadata_content_encoding(metadata)
let content_md5_bytes = native_metadata_content_md5(metadata)
let content_type_bytes = native_metadata_content_type(metadata)
let etag_bytes = native_metadata_etag(metadata)
let version_bytes = native_metadata_version(metadata)
native_metadata_release(metadata)
let mode = match mode_code {
1U => File
2U => Directory
_ => Unknown
}
let is_current = if metadata_bit(bits, 0) {
Some(is_current_value)
} else {
None
}
let last_modified = if metadata_bit(bits, 1) {
Some({
unix_seconds: modified_seconds,
nanoseconds: modified_nanoseconds.reinterpret_as_int(),
})
} else {
None
}
{
mode,
content_length,
is_current,
is_deleted,
cache_control: optional_metadata_text(
metadata_bit(bits, 2),
cache_control_bytes,
operation,
path,
destination_path,
),
content_disposition: optional_metadata_text(
metadata_bit(bits, 3),
content_disposition_bytes,
operation,
path,
destination_path,
),
content_encoding: optional_metadata_text(
metadata_bit(bits, 4),
content_encoding_bytes,
operation,
path,
destination_path,
),
content_md5: optional_metadata_text(
metadata_bit(bits, 5),
content_md5_bytes,
operation,
path,
destination_path,
),
content_type: optional_metadata_text(
metadata_bit(bits, 6),
content_type_bytes,
operation,
path,
destination_path,
),
etag: optional_metadata_text(
metadata_bit(bits, 7),
etag_bytes,
operation,
path,
destination_path,
),
last_modified,
version: optional_metadata_text(
metadata_bit(bits, 8),
version_bytes,
operation,
path,
destination_path,
),
}
}
///|
fn entry_from_native(
entry : NativeEntry,
listing_path : String,
) -> Entry raise OpenDalError {
let path_bytes = native_entry_path(entry)
let name_bytes = native_entry_name(entry)
let metadata = native_entry_take_metadata(entry)
native_entry_release(entry)
let path = decode_abi_text(path_bytes, List, Some(listing_path), None)
let name = decode_abi_text(name_bytes, List, Some(listing_path), None)
{ path, name, metadata: metadata_from_native(metadata, List, Some(path)) }
}