opendal 0.1.6.pre.rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.standard.yml +20 -0
- data/.tool-versions +1 -0
- data/.yardopts +1 -0
- data/Cargo.toml +65 -0
- data/DEPENDENCIES.md +9 -0
- data/DEPENDENCIES.rust.tsv +277 -0
- data/Gemfile +35 -0
- data/README.md +159 -0
- data/Rakefile +149 -0
- data/build.rs +22 -0
- data/core/CHANGELOG.md +4929 -0
- data/core/CONTRIBUTING.md +61 -0
- data/core/Cargo.lock +10259 -0
- data/core/Cargo.toml +437 -0
- data/core/DEPENDENCIES.md +3 -0
- data/core/DEPENDENCIES.rust.tsv +185 -0
- data/core/LICENSE +201 -0
- data/core/README.md +228 -0
- data/core/benches/README.md +18 -0
- data/core/benches/ops/README.md +26 -0
- data/core/benches/ops/main.rs +25 -0
- data/core/benches/ops/read.rs +100 -0
- data/core/benches/ops/utils.rs +59 -0
- data/core/benches/ops/write.rs +106 -0
- data/core/benches/types/README.md +9 -0
- data/core/benches/types/buffer.rs +114 -0
- data/core/benches/types/main.rs +23 -0
- data/core/benches/types/tasks.rs +64 -0
- data/core/benches/vs_fs/Cargo.toml +32 -0
- data/core/benches/vs_fs/README.md +35 -0
- data/core/benches/vs_fs/src/main.rs +83 -0
- data/core/benches/vs_s3/Cargo.toml +38 -0
- data/core/benches/vs_s3/README.md +55 -0
- data/core/benches/vs_s3/src/main.rs +123 -0
- data/core/edge/README.md +3 -0
- data/core/edge/file_write_on_full_disk/Cargo.toml +31 -0
- data/core/edge/file_write_on_full_disk/README.md +14 -0
- data/core/edge/file_write_on_full_disk/src/main.rs +43 -0
- data/core/edge/s3_aws_assume_role_with_web_identity/Cargo.toml +30 -0
- data/core/edge/s3_aws_assume_role_with_web_identity/README.md +18 -0
- data/core/edge/s3_aws_assume_role_with_web_identity/src/main.rs +34 -0
- data/core/edge/s3_read_on_wasm/.gitignore +3 -0
- data/core/edge/s3_read_on_wasm/Cargo.toml +38 -0
- data/core/edge/s3_read_on_wasm/README.md +42 -0
- data/core/edge/s3_read_on_wasm/src/lib.rs +60 -0
- data/core/edge/s3_read_on_wasm/webdriver.json +15 -0
- data/core/examples/README.md +23 -0
- data/core/examples/basic/Cargo.toml +29 -0
- data/core/examples/basic/README.md +15 -0
- data/core/examples/basic/src/main.rs +51 -0
- data/core/examples/concurrent-upload/Cargo.toml +29 -0
- data/core/examples/concurrent-upload/README.md +15 -0
- data/core/examples/concurrent-upload/src/main.rs +68 -0
- data/core/examples/multipart-upload/Cargo.toml +29 -0
- data/core/examples/multipart-upload/README.md +15 -0
- data/core/examples/multipart-upload/src/main.rs +56 -0
- data/core/fuzz/.gitignore +5 -0
- data/core/fuzz/Cargo.toml +92 -0
- data/core/fuzz/README.md +68 -0
- data/core/fuzz/fuzz_reader.rs +102 -0
- data/core/fuzz/fuzz_writer.rs +123 -0
- data/core/src/blocking/delete.rs +74 -0
- data/core/src/blocking/list.rs +71 -0
- data/core/src/blocking/mod.rs +33 -0
- data/core/src/blocking/operator.rs +729 -0
- data/core/src/blocking/read/buffer_iterator.rs +66 -0
- data/core/src/blocking/read/mod.rs +27 -0
- data/core/src/blocking/read/reader.rs +124 -0
- data/core/src/blocking/read/std_bytes_iterator.rs +69 -0
- data/core/src/blocking/read/std_reader.rs +95 -0
- data/core/src/blocking/write/mod.rs +22 -0
- data/core/src/blocking/write/std_writer.rs +82 -0
- data/core/src/blocking/write/writer.rs +109 -0
- data/core/src/docs/comparisons/mod.rs +30 -0
- data/core/src/docs/comparisons/vs_object_store.md +183 -0
- data/core/src/docs/concepts.rs +135 -0
- data/core/src/docs/internals/accessor.rs +306 -0
- data/core/src/docs/internals/layer.rs +42 -0
- data/core/src/docs/internals/mod.rs +62 -0
- data/core/src/docs/mod.rs +43 -0
- data/core/src/docs/performance/concurrent_write.md +101 -0
- data/core/src/docs/performance/http_optimization.md +124 -0
- data/core/src/docs/performance/mod.rs +32 -0
- data/core/src/docs/rfcs/0000_example.md +74 -0
- data/core/src/docs/rfcs/0000_foyer_integration.md +111 -0
- data/core/src/docs/rfcs/0041_object_native_api.md +185 -0
- data/core/src/docs/rfcs/0044_error_handle.md +198 -0
- data/core/src/docs/rfcs/0057_auto_region.md +160 -0
- data/core/src/docs/rfcs/0069_object_stream.md +145 -0
- data/core/src/docs/rfcs/0090_limited_reader.md +155 -0
- data/core/src/docs/rfcs/0112_path_normalization.md +79 -0
- data/core/src/docs/rfcs/0191_async_streaming_io.md +328 -0
- data/core/src/docs/rfcs/0203_remove_credential.md +96 -0
- data/core/src/docs/rfcs/0221_create_dir.md +89 -0
- data/core/src/docs/rfcs/0247_retryable_error.md +87 -0
- data/core/src/docs/rfcs/0293_object_id.md +67 -0
- data/core/src/docs/rfcs/0337_dir_entry.md +191 -0
- data/core/src/docs/rfcs/0409_accessor_capabilities.md +67 -0
- data/core/src/docs/rfcs/0413_presign.md +154 -0
- data/core/src/docs/rfcs/0423_command_line_interface.md +268 -0
- data/core/src/docs/rfcs/0429_init_from_iter.md +107 -0
- data/core/src/docs/rfcs/0438_multipart.md +163 -0
- data/core/src/docs/rfcs/0443_gateway.md +73 -0
- data/core/src/docs/rfcs/0501_new_builder.md +111 -0
- data/core/src/docs/rfcs/0554_write_refactor.md +96 -0
- data/core/src/docs/rfcs/0561_list_metadata_reuse.md +210 -0
- data/core/src/docs/rfcs/0599_blocking_api.md +157 -0
- data/core/src/docs/rfcs/0623_redis_service.md +300 -0
- data/core/src/docs/rfcs/0627_split_capabilities.md +89 -0
- data/core/src/docs/rfcs/0661_path_in_accessor.md +126 -0
- data/core/src/docs/rfcs/0793_generic_kv_services.md +209 -0
- data/core/src/docs/rfcs/0926_object_reader.md +93 -0
- data/core/src/docs/rfcs/0977_refactor_error.md +151 -0
- data/core/src/docs/rfcs/1085_object_handler.md +73 -0
- data/core/src/docs/rfcs/1391_object_metadataer.md +110 -0
- data/core/src/docs/rfcs/1398_query_based_metadata.md +125 -0
- data/core/src/docs/rfcs/1420_object_writer.md +147 -0
- data/core/src/docs/rfcs/1477_remove_object_concept.md +159 -0
- data/core/src/docs/rfcs/1735_operation_extension.md +117 -0
- data/core/src/docs/rfcs/2083_writer_sink_api.md +106 -0
- data/core/src/docs/rfcs/2133_append_api.md +88 -0
- data/core/src/docs/rfcs/2299_chain_based_operator_api.md +99 -0
- data/core/src/docs/rfcs/2602_object_versioning.md +138 -0
- data/core/src/docs/rfcs/2758_merge_append_into_write.md +79 -0
- data/core/src/docs/rfcs/2774_lister_api.md +66 -0
- data/core/src/docs/rfcs/2779_list_with_metakey.md +143 -0
- data/core/src/docs/rfcs/2852_native_capability.md +58 -0
- data/core/src/docs/rfcs/2884_merge_range_read_into_read.md +80 -0
- data/core/src/docs/rfcs/3017_remove_write_copy_from.md +94 -0
- data/core/src/docs/rfcs/3197_config.md +237 -0
- data/core/src/docs/rfcs/3232_align_list_api.md +69 -0
- data/core/src/docs/rfcs/3243_list_prefix.md +128 -0
- data/core/src/docs/rfcs/3356_lazy_reader.md +111 -0
- data/core/src/docs/rfcs/3526_list_recursive.md +59 -0
- data/core/src/docs/rfcs/3574_concurrent_stat_in_list.md +80 -0
- data/core/src/docs/rfcs/3734_buffered_reader.md +64 -0
- data/core/src/docs/rfcs/3898_concurrent_writer.md +66 -0
- data/core/src/docs/rfcs/3911_deleter_api.md +165 -0
- data/core/src/docs/rfcs/4382_range_based_read.md +213 -0
- data/core/src/docs/rfcs/4638_executor.md +215 -0
- data/core/src/docs/rfcs/5314_remove_metakey.md +120 -0
- data/core/src/docs/rfcs/5444_operator_from_uri.md +162 -0
- data/core/src/docs/rfcs/5479_context.md +140 -0
- data/core/src/docs/rfcs/5485_conditional_reader.md +112 -0
- data/core/src/docs/rfcs/5495_list_with_deleted.md +81 -0
- data/core/src/docs/rfcs/5556_write_returns_metadata.md +121 -0
- data/core/src/docs/rfcs/5871_read_returns_metadata.md +112 -0
- data/core/src/docs/rfcs/6189_remove_native_blocking.md +106 -0
- data/core/src/docs/rfcs/6209_glob_support.md +132 -0
- data/core/src/docs/rfcs/6213_options_api.md +142 -0
- data/core/src/docs/rfcs/README.md +62 -0
- data/core/src/docs/rfcs/mod.rs +278 -0
- data/core/src/docs/upgrade.md +1556 -0
- data/core/src/layers/async_backtrace.rs +174 -0
- data/core/src/layers/await_tree.rs +202 -0
- data/core/src/layers/capability_check.rs +239 -0
- data/core/src/layers/chaos.rs +170 -0
- data/core/src/layers/complete.rs +385 -0
- data/core/src/layers/concurrent_limit.rs +322 -0
- data/core/src/layers/correctness_check.rs +440 -0
- data/core/src/layers/dtrace.rs +294 -0
- data/core/src/layers/error_context.rs +310 -0
- data/core/src/layers/fastmetrics.rs +525 -0
- data/core/src/layers/fastrace.rs +271 -0
- data/core/src/layers/http_client.rs +206 -0
- data/core/src/layers/immutable_index.rs +408 -0
- data/core/src/layers/logging.rs +842 -0
- data/core/src/layers/metrics.rs +182 -0
- data/core/src/layers/mime_guess.rs +199 -0
- data/core/src/layers/mod.rs +130 -0
- data/core/src/layers/observe/metrics.rs +936 -0
- data/core/src/layers/observe/mod.rs +93 -0
- data/core/src/layers/otelmetrics.rs +496 -0
- data/core/src/layers/oteltrace.rs +203 -0
- data/core/src/layers/prometheus.rs +686 -0
- data/core/src/layers/prometheus_client.rs +519 -0
- data/core/src/layers/retry.rs +933 -0
- data/core/src/layers/throttle.rs +204 -0
- data/core/src/layers/timeout.rs +513 -0
- data/core/src/layers/tracing.rs +349 -0
- data/core/src/layers/type_eraser.rs +91 -0
- data/core/src/lib.rs +204 -0
- data/core/src/raw/accessor.rs +856 -0
- data/core/src/raw/adapters/kv/api.rs +164 -0
- data/core/src/raw/adapters/kv/backend.rs +253 -0
- data/core/src/raw/adapters/kv/mod.rs +31 -0
- data/core/src/raw/adapters/mod.rs +50 -0
- data/core/src/raw/adapters/typed_kv/api.rs +171 -0
- data/core/src/raw/adapters/typed_kv/backend.rs +279 -0
- data/core/src/raw/adapters/typed_kv/mod.rs +29 -0
- data/core/src/raw/atomic_util.rs +57 -0
- data/core/src/raw/azure.rs +570 -0
- data/core/src/raw/chrono_util.rs +109 -0
- data/core/src/raw/enum_utils.rs +201 -0
- data/core/src/raw/futures_util.rs +470 -0
- data/core/src/raw/http_util/body.rs +144 -0
- data/core/src/raw/http_util/bytes_content_range.rs +239 -0
- data/core/src/raw/http_util/bytes_range.rs +260 -0
- data/core/src/raw/http_util/client.rs +276 -0
- data/core/src/raw/http_util/error.rs +68 -0
- data/core/src/raw/http_util/header.rs +356 -0
- data/core/src/raw/http_util/mod.rs +78 -0
- data/core/src/raw/http_util/multipart.rs +1180 -0
- data/core/src/raw/http_util/uri.rs +190 -0
- data/core/src/raw/layer.rs +295 -0
- data/core/src/raw/mod.rs +101 -0
- data/core/src/raw/oio/buf/flex_buf.rs +118 -0
- data/core/src/raw/oio/buf/mod.rs +25 -0
- data/core/src/raw/oio/buf/pooled_buf.rs +126 -0
- data/core/src/raw/oio/buf/queue_buf.rs +117 -0
- data/core/src/raw/oio/delete/api.rs +102 -0
- data/core/src/raw/oio/delete/batch_delete.rs +127 -0
- data/core/src/raw/oio/delete/mod.rs +30 -0
- data/core/src/raw/oio/delete/one_shot_delete.rs +79 -0
- data/core/src/raw/oio/entry.rs +89 -0
- data/core/src/raw/oio/list/api.rs +69 -0
- data/core/src/raw/oio/list/flat_list.rs +137 -0
- data/core/src/raw/oio/list/hierarchy_list.rs +135 -0
- data/core/src/raw/oio/list/mod.rs +35 -0
- data/core/src/raw/oio/list/page_list.rs +105 -0
- data/core/src/raw/oio/list/prefix_list.rs +64 -0
- data/core/src/raw/oio/mod.rs +40 -0
- data/core/src/raw/oio/read/api.rs +119 -0
- data/core/src/raw/oio/read/mod.rs +21 -0
- data/core/src/raw/oio/write/api.rs +103 -0
- data/core/src/raw/oio/write/append_write.rs +111 -0
- data/core/src/raw/oio/write/block_write.rs +405 -0
- data/core/src/raw/oio/write/mod.rs +42 -0
- data/core/src/raw/oio/write/multipart_write.rs +518 -0
- data/core/src/raw/oio/write/one_shot_write.rs +77 -0
- data/core/src/raw/oio/write/position_write.rs +284 -0
- data/core/src/raw/operation.rs +88 -0
- data/core/src/raw/ops.rs +917 -0
- data/core/src/raw/path.rs +451 -0
- data/core/src/raw/path_cache.rs +244 -0
- data/core/src/raw/rps.rs +249 -0
- data/core/src/raw/serde_util.rs +423 -0
- data/core/src/raw/std_io_util.rs +65 -0
- data/core/src/raw/tests/mod.rs +30 -0
- data/core/src/raw/tests/read.rs +116 -0
- data/core/src/raw/tests/utils.rs +80 -0
- data/core/src/raw/tests/write.rs +79 -0
- data/core/src/raw/tokio_util.rs +24 -0
- data/core/src/raw/version.rs +19 -0
- data/core/src/services/aliyun_drive/backend.rs +421 -0
- data/core/src/services/aliyun_drive/config.rs +72 -0
- data/core/src/services/aliyun_drive/core.rs +651 -0
- data/core/src/services/aliyun_drive/delete.rs +51 -0
- data/core/src/services/aliyun_drive/docs.md +61 -0
- data/core/src/services/aliyun_drive/error.rs +56 -0
- data/core/src/services/aliyun_drive/lister.rs +134 -0
- data/core/src/services/aliyun_drive/mod.rs +39 -0
- data/core/src/services/aliyun_drive/writer.rs +114 -0
- data/core/src/services/alluxio/backend.rs +257 -0
- data/core/src/services/alluxio/config.rs +50 -0
- data/core/src/services/alluxio/core.rs +367 -0
- data/core/src/services/alluxio/delete.rs +38 -0
- data/core/src/services/alluxio/docs.md +45 -0
- data/core/src/services/alluxio/error.rs +99 -0
- data/core/src/services/alluxio/lister.rs +73 -0
- data/core/src/services/alluxio/mod.rs +39 -0
- data/core/src/services/alluxio/writer.rs +74 -0
- data/core/src/services/azblob/backend.rs +594 -0
- data/core/src/services/azblob/config.rs +220 -0
- data/core/src/services/azblob/core.rs +937 -0
- data/core/src/services/azblob/delete.rs +108 -0
- data/core/src/services/azblob/docs.md +77 -0
- data/core/src/services/azblob/error.rs +164 -0
- data/core/src/services/azblob/lister.rs +107 -0
- data/core/src/services/azblob/mod.rs +38 -0
- data/core/src/services/azblob/writer.rs +177 -0
- data/core/src/services/azdls/backend.rs +435 -0
- data/core/src/services/azdls/config.rs +89 -0
- data/core/src/services/azdls/core.rs +388 -0
- data/core/src/services/azdls/delete.rs +48 -0
- data/core/src/services/azdls/docs.md +73 -0
- data/core/src/services/azdls/error.rs +107 -0
- data/core/src/services/azdls/lister.rs +165 -0
- data/core/src/services/azdls/mod.rs +38 -0
- data/core/src/services/azdls/writer.rs +129 -0
- data/core/src/services/azfile/backend.rs +373 -0
- data/core/src/services/azfile/config.rs +61 -0
- data/core/src/services/azfile/core.rs +435 -0
- data/core/src/services/azfile/delete.rs +51 -0
- data/core/src/services/azfile/docs.md +65 -0
- data/core/src/services/azfile/error.rs +108 -0
- data/core/src/services/azfile/lister.rs +217 -0
- data/core/src/services/azfile/mod.rs +39 -0
- data/core/src/services/azfile/writer.rs +92 -0
- data/core/src/services/b2/backend.rs +434 -0
- data/core/src/services/b2/config.rs +64 -0
- data/core/src/services/b2/core.rs +742 -0
- data/core/src/services/b2/delete.rs +56 -0
- data/core/src/services/b2/docs.md +54 -0
- data/core/src/services/b2/error.rs +132 -0
- data/core/src/services/b2/lister.rs +110 -0
- data/core/src/services/b2/mod.rs +39 -0
- data/core/src/services/b2/writer.rs +189 -0
- data/core/src/services/cacache/backend.rs +160 -0
- data/core/src/services/cacache/config.rs +28 -0
- data/core/src/services/cacache/core.rs +96 -0
- data/core/src/services/cacache/delete.rs +39 -0
- data/core/src/services/cacache/docs.md +38 -0
- data/core/src/services/cacache/mod.rs +34 -0
- data/core/src/services/cacache/writer.rs +61 -0
- data/core/src/services/cloudflare_kv/backend.rs +513 -0
- data/core/src/services/cloudflare_kv/config.rs +55 -0
- data/core/src/services/cloudflare_kv/core.rs +168 -0
- data/core/src/services/cloudflare_kv/delete.rs +119 -0
- data/core/src/services/cloudflare_kv/docs.md +21 -0
- data/core/src/services/cloudflare_kv/error.rs +79 -0
- data/core/src/services/cloudflare_kv/lister.rs +170 -0
- data/core/src/services/cloudflare_kv/mod.rs +39 -0
- data/core/src/services/cloudflare_kv/model.rs +76 -0
- data/core/src/services/cloudflare_kv/writer.rs +68 -0
- data/core/src/services/compfs/backend.rs +290 -0
- data/core/src/services/compfs/config.rs +30 -0
- data/core/src/services/compfs/core.rs +159 -0
- data/core/src/services/compfs/delete.rs +53 -0
- data/core/src/services/compfs/lister.rs +98 -0
- data/core/src/services/compfs/mod.rs +38 -0
- data/core/src/services/compfs/reader.rs +79 -0
- data/core/src/services/compfs/writer.rs +90 -0
- data/core/src/services/cos/backend.rs +442 -0
- data/core/src/services/cos/config.rs +54 -0
- data/core/src/services/cos/core.rs +761 -0
- data/core/src/services/cos/delete.rs +48 -0
- data/core/src/services/cos/docs.md +55 -0
- data/core/src/services/cos/error.rs +105 -0
- data/core/src/services/cos/lister.rs +237 -0
- data/core/src/services/cos/mod.rs +39 -0
- data/core/src/services/cos/writer.rs +234 -0
- data/core/src/services/d1/backend.rs +330 -0
- data/core/src/services/d1/config.rs +55 -0
- data/core/src/services/d1/docs.md +48 -0
- data/core/src/services/d1/error.rs +79 -0
- data/core/src/services/d1/mod.rs +29 -0
- data/core/src/services/d1/model.rs +125 -0
- data/core/src/services/dashmap/backend.rs +203 -0
- data/core/src/services/dashmap/config.rs +37 -0
- data/core/src/services/dashmap/core.rs +61 -0
- data/core/src/services/dashmap/delete.rs +40 -0
- data/core/src/services/dashmap/docs.md +38 -0
- data/core/src/services/dashmap/lister.rs +63 -0
- data/core/src/services/dashmap/mod.rs +36 -0
- data/core/src/services/dashmap/writer.rs +87 -0
- data/core/src/services/dbfs/backend.rs +258 -0
- data/core/src/services/dbfs/config.rs +48 -0
- data/core/src/services/dbfs/core.rs +191 -0
- data/core/src/services/dbfs/delete.rs +49 -0
- data/core/src/services/dbfs/docs.md +57 -0
- data/core/src/services/dbfs/error.rs +74 -0
- data/core/src/services/dbfs/lister.rs +96 -0
- data/core/src/services/dbfs/mod.rs +38 -0
- data/core/src/services/dbfs/writer.rs +64 -0
- data/core/src/services/dropbox/backend.rs +187 -0
- data/core/src/services/dropbox/builder.rs +222 -0
- data/core/src/services/dropbox/config.rs +47 -0
- data/core/src/services/dropbox/core.rs +496 -0
- data/core/src/services/dropbox/delete.rs +54 -0
- data/core/src/services/dropbox/docs.md +64 -0
- data/core/src/services/dropbox/error.rs +85 -0
- data/core/src/services/dropbox/lister.rs +117 -0
- data/core/src/services/dropbox/mod.rs +40 -0
- data/core/src/services/dropbox/writer.rs +51 -0
- data/core/src/services/etcd/backend.rs +345 -0
- data/core/src/services/etcd/config.rs +86 -0
- data/core/src/services/etcd/core.rs +143 -0
- data/core/src/services/etcd/deleter.rs +41 -0
- data/core/src/services/etcd/docs.md +45 -0
- data/core/src/services/etcd/error.rs +26 -0
- data/core/src/services/etcd/lister.rs +79 -0
- data/core/src/services/etcd/mod.rs +36 -0
- data/core/src/services/etcd/writer.rs +61 -0
- data/core/src/services/foundationdb/backend.rs +171 -0
- data/core/src/services/foundationdb/config.rs +45 -0
- data/core/src/services/foundationdb/docs.md +42 -0
- data/core/src/services/foundationdb/mod.rs +24 -0
- data/core/src/services/fs/backend.rs +299 -0
- data/core/src/services/fs/config.rs +33 -0
- data/core/src/services/fs/core.rs +227 -0
- data/core/src/services/fs/delete.rs +53 -0
- data/core/src/services/fs/docs.md +49 -0
- data/core/src/services/fs/error.rs +31 -0
- data/core/src/services/fs/lister.rs +81 -0
- data/core/src/services/fs/mod.rs +40 -0
- data/core/src/services/fs/reader.rs +83 -0
- data/core/src/services/fs/writer.rs +212 -0
- data/core/src/services/ftp/backend.rs +388 -0
- data/core/src/services/ftp/config.rs +46 -0
- data/core/src/services/ftp/core.rs +136 -0
- data/core/src/services/ftp/delete.rs +62 -0
- data/core/src/services/ftp/docs.md +42 -0
- data/core/src/services/ftp/err.rs +47 -0
- data/core/src/services/ftp/lister.rs +72 -0
- data/core/src/services/ftp/mod.rs +41 -0
- data/core/src/services/ftp/reader.rs +84 -0
- data/core/src/services/ftp/writer.rs +122 -0
- data/core/src/services/gcs/backend.rs +499 -0
- data/core/src/services/gcs/config.rs +168 -0
- data/core/src/services/gcs/core.rs +1079 -0
- data/core/src/services/gcs/delete.rs +98 -0
- data/core/src/services/gcs/docs.md +76 -0
- data/core/src/services/gcs/error.rs +122 -0
- data/core/src/services/gcs/lister.rs +136 -0
- data/core/src/services/gcs/mod.rs +40 -0
- data/core/src/services/gcs/uri.rs +75 -0
- data/core/src/services/gcs/writer.rs +163 -0
- data/core/src/services/gdrive/backend.rs +176 -0
- data/core/src/services/gdrive/builder.rs +228 -0
- data/core/src/services/gdrive/config.rs +47 -0
- data/core/src/services/gdrive/core.rs +499 -0
- data/core/src/services/gdrive/delete.rs +57 -0
- data/core/src/services/gdrive/docs.md +65 -0
- data/core/src/services/gdrive/error.rs +80 -0
- data/core/src/services/gdrive/lister.rs +110 -0
- data/core/src/services/gdrive/mod.rs +40 -0
- data/core/src/services/gdrive/writer.rs +77 -0
- data/core/src/services/ghac/backend.rs +285 -0
- data/core/src/services/ghac/config.rs +36 -0
- data/core/src/services/ghac/core.rs +459 -0
- data/core/src/services/ghac/docs.md +84 -0
- data/core/src/services/ghac/error.rs +52 -0
- data/core/src/services/ghac/mod.rs +35 -0
- data/core/src/services/ghac/writer.rs +201 -0
- data/core/src/services/github/backend.rs +285 -0
- data/core/src/services/github/config.rs +59 -0
- data/core/src/services/github/core.rs +351 -0
- data/core/src/services/github/delete.rs +41 -0
- data/core/src/services/github/docs.md +52 -0
- data/core/src/services/github/error.rs +101 -0
- data/core/src/services/github/lister.rs +112 -0
- data/core/src/services/github/mod.rs +38 -0
- data/core/src/services/github/writer.rs +51 -0
- data/core/src/services/gridfs/backend.rs +166 -0
- data/core/src/services/gridfs/config.rs +50 -0
- data/core/src/services/gridfs/core.rs +154 -0
- data/core/src/services/gridfs/docs.md +46 -0
- data/core/src/services/gridfs/mod.rs +26 -0
- data/core/src/services/hdfs/backend.rs +413 -0
- data/core/src/services/hdfs/config.rs +59 -0
- data/core/src/services/hdfs/delete.rs +62 -0
- data/core/src/services/hdfs/docs.md +140 -0
- data/core/src/services/hdfs/lister.rs +70 -0
- data/core/src/services/hdfs/mod.rs +36 -0
- data/core/src/services/hdfs/reader.rs +79 -0
- data/core/src/services/hdfs/writer.rs +104 -0
- data/core/src/services/hdfs_native/backend.rs +340 -0
- data/core/src/services/hdfs_native/config.rs +45 -0
- data/core/src/services/hdfs_native/delete.rs +47 -0
- data/core/src/services/hdfs_native/docs.md +35 -0
- data/core/src/services/hdfs_native/error.rs +59 -0
- data/core/src/services/hdfs_native/lister.rs +85 -0
- data/core/src/services/hdfs_native/mod.rs +39 -0
- data/core/src/services/hdfs_native/reader.rs +62 -0
- data/core/src/services/hdfs_native/writer.rs +61 -0
- data/core/src/services/http/backend.rs +291 -0
- data/core/src/services/http/config.rs +49 -0
- data/core/src/services/http/core.rs +125 -0
- data/core/src/services/http/docs.md +45 -0
- data/core/src/services/http/error.rs +53 -0
- data/core/src/services/http/mod.rs +32 -0
- data/core/src/services/huggingface/backend.rs +289 -0
- data/core/src/services/huggingface/config.rs +75 -0
- data/core/src/services/huggingface/core.rs +406 -0
- data/core/src/services/huggingface/docs.md +61 -0
- data/core/src/services/huggingface/error.rs +93 -0
- data/core/src/services/huggingface/lister.rs +91 -0
- data/core/src/services/huggingface/mod.rs +34 -0
- data/core/src/services/ipfs/backend.rs +257 -0
- data/core/src/services/ipfs/config.rs +32 -0
- data/core/src/services/ipfs/core.rs +239 -0
- data/core/src/services/ipfs/docs.md +45 -0
- data/core/src/services/ipfs/error.rs +52 -0
- data/core/src/services/ipfs/ipld.rs +162 -0
- data/core/src/services/ipfs/mod.rs +34 -0
- data/core/src/services/ipmfs/backend.rs +147 -0
- data/core/src/services/ipmfs/builder.rs +166 -0
- data/core/src/services/ipmfs/config.rs +32 -0
- data/core/src/services/ipmfs/core.rs +142 -0
- data/core/src/services/ipmfs/delete.rs +48 -0
- data/core/src/services/ipmfs/docs.md +14 -0
- data/core/src/services/ipmfs/error.rs +83 -0
- data/core/src/services/ipmfs/lister.rs +135 -0
- data/core/src/services/ipmfs/mod.rs +40 -0
- data/core/src/services/ipmfs/writer.rs +49 -0
- data/core/src/services/koofr/backend.rs +361 -0
- data/core/src/services/koofr/config.rs +50 -0
- data/core/src/services/koofr/core.rs +458 -0
- data/core/src/services/koofr/delete.rs +50 -0
- data/core/src/services/koofr/docs.md +51 -0
- data/core/src/services/koofr/error.rs +72 -0
- data/core/src/services/koofr/lister.rs +88 -0
- data/core/src/services/koofr/mod.rs +38 -0
- data/core/src/services/koofr/writer.rs +53 -0
- data/core/src/services/lakefs/backend.rs +309 -0
- data/core/src/services/lakefs/config.rs +81 -0
- data/core/src/services/lakefs/core.rs +261 -0
- data/core/src/services/lakefs/delete.rs +54 -0
- data/core/src/services/lakefs/docs.md +62 -0
- data/core/src/services/lakefs/error.rs +93 -0
- data/core/src/services/lakefs/lister.rs +120 -0
- data/core/src/services/lakefs/mod.rs +38 -0
- data/core/src/services/lakefs/writer.rs +50 -0
- data/core/src/services/memcached/backend.rs +284 -0
- data/core/src/services/memcached/binary.rs +289 -0
- data/core/src/services/memcached/config.rs +43 -0
- data/core/src/services/memcached/docs.md +47 -0
- data/core/src/services/memcached/mod.rs +27 -0
- data/core/src/services/memory/backend.rs +205 -0
- data/core/src/services/memory/config.rs +30 -0
- data/core/src/services/memory/core.rs +80 -0
- data/core/src/services/memory/delete.rs +42 -0
- data/core/src/services/memory/docs.md +36 -0
- data/core/src/services/memory/lister.rs +56 -0
- data/core/src/services/memory/mod.rs +36 -0
- data/core/src/services/memory/writer.rs +85 -0
- data/core/src/services/mini_moka/backend.rs +260 -0
- data/core/src/services/mini_moka/config.rs +56 -0
- data/core/src/services/mini_moka/core.rs +52 -0
- data/core/src/services/mini_moka/delete.rs +42 -0
- data/core/src/services/mini_moka/docs.md +19 -0
- data/core/src/services/mini_moka/lister.rs +68 -0
- data/core/src/services/mini_moka/mod.rs +36 -0
- data/core/src/services/mini_moka/writer.rs +84 -0
- data/core/src/services/mod.rs +206 -0
- data/core/src/services/moka/backend.rs +326 -0
- data/core/src/services/moka/config.rs +59 -0
- data/core/src/services/moka/core.rs +62 -0
- data/core/src/services/moka/delete.rs +42 -0
- data/core/src/services/moka/docs.md +42 -0
- data/core/src/services/moka/lister.rs +65 -0
- data/core/src/services/moka/mod.rs +41 -0
- data/core/src/services/moka/writer.rs +83 -0
- data/core/src/services/mongodb/backend.rs +291 -0
- data/core/src/services/mongodb/config.rs +54 -0
- data/core/src/services/mongodb/docs.md +49 -0
- data/core/src/services/mongodb/mod.rs +24 -0
- data/core/src/services/monoiofs/backend.rs +238 -0
- data/core/src/services/monoiofs/config.rs +34 -0
- data/core/src/services/monoiofs/core.rs +313 -0
- data/core/src/services/monoiofs/delete.rs +64 -0
- data/core/src/services/monoiofs/docs.md +46 -0
- data/core/src/services/monoiofs/mod.rs +36 -0
- data/core/src/services/monoiofs/reader.rs +147 -0
- data/core/src/services/monoiofs/writer.rs +189 -0
- data/core/src/services/mysql/backend.rs +256 -0
- data/core/src/services/mysql/config.rs +66 -0
- data/core/src/services/mysql/docs.md +47 -0
- data/core/src/services/mysql/mod.rs +24 -0
- data/core/src/services/obs/backend.rs +442 -0
- data/core/src/services/obs/config.rs +53 -0
- data/core/src/services/obs/core.rs +608 -0
- data/core/src/services/obs/delete.rs +48 -0
- data/core/src/services/obs/docs.md +54 -0
- data/core/src/services/obs/error.rs +106 -0
- data/core/src/services/obs/lister.rs +101 -0
- data/core/src/services/obs/mod.rs +38 -0
- data/core/src/services/obs/writer.rs +235 -0
- data/core/src/services/onedrive/backend.rs +127 -0
- data/core/src/services/onedrive/builder.rs +236 -0
- data/core/src/services/onedrive/config.rs +49 -0
- data/core/src/services/onedrive/core.rs +691 -0
- data/core/src/services/onedrive/delete.rs +47 -0
- data/core/src/services/onedrive/docs.md +115 -0
- data/core/src/services/onedrive/error.rs +61 -0
- data/core/src/services/onedrive/graph_model.rs +425 -0
- data/core/src/services/onedrive/lister.rs +150 -0
- data/core/src/services/onedrive/mod.rs +42 -0
- data/core/src/services/onedrive/writer.rs +168 -0
- data/core/src/services/opfs/backend.rs +50 -0
- data/core/src/services/opfs/config.rs +25 -0
- data/core/src/services/opfs/core.rs +74 -0
- data/core/src/services/opfs/docs.md +18 -0
- data/core/src/services/opfs/error.rs +27 -0
- data/core/src/services/opfs/mod.rs +30 -0
- data/core/src/services/opfs/utils.rs +70 -0
- data/core/src/services/oss/backend.rs +734 -0
- data/core/src/services/oss/config.rs +113 -0
- data/core/src/services/oss/core.rs +1088 -0
- data/core/src/services/oss/delete.rs +109 -0
- data/core/src/services/oss/docs.md +74 -0
- data/core/src/services/oss/error.rs +109 -0
- data/core/src/services/oss/lister.rs +256 -0
- data/core/src/services/oss/mod.rs +38 -0
- data/core/src/services/oss/writer.rs +228 -0
- data/core/src/services/pcloud/backend.rs +358 -0
- data/core/src/services/pcloud/config.rs +51 -0
- data/core/src/services/pcloud/core.rs +461 -0
- data/core/src/services/pcloud/delete.rs +66 -0
- data/core/src/services/pcloud/docs.md +51 -0
- data/core/src/services/pcloud/error.rs +88 -0
- data/core/src/services/pcloud/lister.rs +95 -0
- data/core/src/services/pcloud/mod.rs +38 -0
- data/core/src/services/pcloud/writer.rs +66 -0
- data/core/src/services/persy/backend.rs +226 -0
- data/core/src/services/persy/config.rs +32 -0
- data/core/src/services/persy/docs.md +43 -0
- data/core/src/services/persy/mod.rs +24 -0
- data/core/src/services/postgresql/backend.rs +258 -0
- data/core/src/services/postgresql/config.rs +66 -0
- data/core/src/services/postgresql/docs.md +47 -0
- data/core/src/services/postgresql/mod.rs +24 -0
- data/core/src/services/redb/backend.rs +280 -0
- data/core/src/services/redb/config.rs +34 -0
- data/core/src/services/redb/docs.md +41 -0
- data/core/src/services/redb/mod.rs +24 -0
- data/core/src/services/redis/backend.rs +442 -0
- data/core/src/services/redis/config.rs +79 -0
- data/core/src/services/redis/core.rs +209 -0
- data/core/src/services/redis/delete.rs +40 -0
- data/core/src/services/redis/docs.md +43 -0
- data/core/src/services/redis/mod.rs +34 -0
- data/core/src/services/redis/writer.rs +57 -0
- data/core/src/services/rocksdb/backend.rs +159 -0
- data/core/src/services/rocksdb/config.rs +34 -0
- data/core/src/services/rocksdb/docs.md +54 -0
- data/core/src/services/rocksdb/mod.rs +24 -0
- data/core/src/services/s3/backend.rs +1293 -0
- data/core/src/services/s3/compatible_services.md +126 -0
- data/core/src/services/s3/config.rs +327 -0
- data/core/src/services/s3/core.rs +1741 -0
- data/core/src/services/s3/delete.rs +109 -0
- data/core/src/services/s3/docs.md +244 -0
- data/core/src/services/s3/error.rs +171 -0
- data/core/src/services/s3/lister.rs +405 -0
- data/core/src/services/s3/mod.rs +38 -0
- data/core/src/services/s3/writer.rs +262 -0
- data/core/src/services/seafile/backend.rs +297 -0
- data/core/src/services/seafile/config.rs +56 -0
- data/core/src/services/seafile/core.rs +475 -0
- data/core/src/services/seafile/delete.rs +40 -0
- data/core/src/services/seafile/docs.md +54 -0
- data/core/src/services/seafile/error.rs +86 -0
- data/core/src/services/seafile/lister.rs +83 -0
- data/core/src/services/seafile/mod.rs +38 -0
- data/core/src/services/seafile/writer.rs +55 -0
- data/core/src/services/sftp/backend.rs +397 -0
- data/core/src/services/sftp/config.rs +50 -0
- data/core/src/services/sftp/core.rs +154 -0
- data/core/src/services/sftp/delete.rs +55 -0
- data/core/src/services/sftp/docs.md +49 -0
- data/core/src/services/sftp/error.rs +57 -0
- data/core/src/services/sftp/lister.rs +88 -0
- data/core/src/services/sftp/mod.rs +42 -0
- data/core/src/services/sftp/reader.rs +78 -0
- data/core/src/services/sftp/utils.rs +51 -0
- data/core/src/services/sftp/writer.rs +67 -0
- data/core/src/services/sled/backend.rs +194 -0
- data/core/src/services/sled/config.rs +45 -0
- data/core/src/services/sled/docs.md +39 -0
- data/core/src/services/sled/mod.rs +24 -0
- data/core/src/services/sqlite/backend.rs +326 -0
- data/core/src/services/sqlite/config.rs +70 -0
- data/core/src/services/sqlite/docs.md +46 -0
- data/core/src/services/sqlite/mod.rs +24 -0
- data/core/src/services/surrealdb/backend.rs +365 -0
- data/core/src/services/surrealdb/config.rs +64 -0
- data/core/src/services/surrealdb/docs.md +54 -0
- data/core/src/services/surrealdb/mod.rs +24 -0
- data/core/src/services/swift/backend.rs +275 -0
- data/core/src/services/swift/compatible_services.md +53 -0
- data/core/src/services/swift/config.rs +53 -0
- data/core/src/services/swift/core.rs +310 -0
- data/core/src/services/swift/delete.rs +49 -0
- data/core/src/services/swift/docs.md +52 -0
- data/core/src/services/swift/error.rs +90 -0
- data/core/src/services/swift/lister.rs +119 -0
- data/core/src/services/swift/mod.rs +38 -0
- data/core/src/services/swift/writer.rs +53 -0
- data/core/src/services/tikv/backend.rs +237 -0
- data/core/src/services/tikv/config.rs +52 -0
- data/core/src/services/tikv/docs.md +43 -0
- data/core/src/services/tikv/mod.rs +24 -0
- data/core/src/services/upyun/backend.rs +317 -0
- data/core/src/services/upyun/config.rs +51 -0
- data/core/src/services/upyun/core.rs +521 -0
- data/core/src/services/upyun/delete.rs +50 -0
- data/core/src/services/upyun/docs.md +51 -0
- data/core/src/services/upyun/error.rs +97 -0
- data/core/src/services/upyun/lister.rs +101 -0
- data/core/src/services/upyun/mod.rs +38 -0
- data/core/src/services/upyun/writer.rs +127 -0
- data/core/src/services/vercel_artifacts/backend.rs +99 -0
- data/core/src/services/vercel_artifacts/builder.rs +117 -0
- data/core/src/services/vercel_artifacts/config.rs +39 -0
- data/core/src/services/vercel_artifacts/core.rs +112 -0
- data/core/src/services/vercel_artifacts/docs.md +40 -0
- data/core/src/services/vercel_artifacts/error.rs +50 -0
- data/core/src/services/vercel_artifacts/mod.rs +36 -0
- data/core/src/services/vercel_artifacts/writer.rs +58 -0
- data/core/src/services/vercel_blob/backend.rs +251 -0
- data/core/src/services/vercel_blob/config.rs +45 -0
- data/core/src/services/vercel_blob/core.rs +449 -0
- data/core/src/services/vercel_blob/delete.rs +38 -0
- data/core/src/services/vercel_blob/docs.md +45 -0
- data/core/src/services/vercel_blob/error.rs +110 -0
- data/core/src/services/vercel_blob/lister.rs +69 -0
- data/core/src/services/vercel_blob/mod.rs +38 -0
- data/core/src/services/vercel_blob/writer.rs +143 -0
- data/core/src/services/webdav/backend.rs +318 -0
- data/core/src/services/webdav/config.rs +53 -0
- data/core/src/services/webdav/core.rs +859 -0
- data/core/src/services/webdav/delete.rs +47 -0
- data/core/src/services/webdav/docs.md +49 -0
- data/core/src/services/webdav/error.rs +53 -0
- data/core/src/services/webdav/lister.rs +106 -0
- data/core/src/services/webdav/mod.rs +38 -0
- data/core/src/services/webdav/writer.rs +56 -0
- data/core/src/services/webhdfs/backend.rs +376 -0
- data/core/src/services/webhdfs/config.rs +52 -0
- data/core/src/services/webhdfs/core.rs +398 -0
- data/core/src/services/webhdfs/delete.rs +46 -0
- data/core/src/services/webhdfs/docs.md +90 -0
- data/core/src/services/webhdfs/error.rs +126 -0
- data/core/src/services/webhdfs/lister.rs +130 -0
- data/core/src/services/webhdfs/message.rs +249 -0
- data/core/src/services/webhdfs/mod.rs +41 -0
- data/core/src/services/webhdfs/writer.rs +177 -0
- data/core/src/services/yandex_disk/backend.rs +267 -0
- data/core/src/services/yandex_disk/config.rs +45 -0
- data/core/src/services/yandex_disk/core.rs +340 -0
- data/core/src/services/yandex_disk/delete.rs +54 -0
- data/core/src/services/yandex_disk/docs.md +45 -0
- data/core/src/services/yandex_disk/error.rs +104 -0
- data/core/src/services/yandex_disk/lister.rs +113 -0
- data/core/src/services/yandex_disk/mod.rs +38 -0
- data/core/src/services/yandex_disk/writer.rs +52 -0
- data/core/src/types/buffer.rs +991 -0
- data/core/src/types/builder.rs +152 -0
- data/core/src/types/capability.rs +209 -0
- data/core/src/types/context/mod.rs +22 -0
- data/core/src/types/context/read.rs +231 -0
- data/core/src/types/context/write.rs +441 -0
- data/core/src/types/delete/deleter.rs +220 -0
- data/core/src/types/delete/futures_delete_sink.rs +176 -0
- data/core/src/types/delete/input.rs +97 -0
- data/core/src/types/delete/mod.rs +26 -0
- data/core/src/types/entry.rs +69 -0
- data/core/src/types/error.rs +570 -0
- data/core/src/types/execute/api.rs +110 -0
- data/core/src/types/execute/executor.rs +96 -0
- data/core/src/types/execute/executors/mod.rs +27 -0
- data/core/src/types/execute/executors/tokio_executor.rs +60 -0
- data/core/src/types/execute/mod.rs +25 -0
- data/core/src/types/list.rs +137 -0
- data/core/src/types/metadata.rs +436 -0
- data/core/src/types/mod.rs +72 -0
- data/core/src/types/mode.rs +68 -0
- data/core/src/types/operator/builder.rs +535 -0
- data/core/src/types/operator/info.rs +63 -0
- data/core/src/types/operator/mod.rs +33 -0
- data/core/src/types/operator/operator.rs +2236 -0
- data/core/src/types/operator/operator_futures.rs +1430 -0
- data/core/src/types/operator/registry.rs +129 -0
- data/core/src/types/options.rs +548 -0
- data/core/src/types/read/buffer_stream.rs +273 -0
- data/core/src/types/read/futures_async_reader.rs +289 -0
- data/core/src/types/read/futures_bytes_stream.rs +157 -0
- data/core/src/types/read/mod.rs +29 -0
- data/core/src/types/read/reader.rs +604 -0
- data/core/src/types/scheme.rs +475 -0
- data/core/src/types/write/buffer_sink.rs +188 -0
- data/core/src/types/write/futures_async_writer.rs +136 -0
- data/core/src/types/write/futures_bytes_sink.rs +103 -0
- data/core/src/types/write/mod.rs +26 -0
- data/core/src/types/write/writer.rs +411 -0
- data/core/tests/behavior/README.md +77 -0
- data/core/tests/behavior/async_copy.rs +314 -0
- data/core/tests/behavior/async_create_dir.rs +53 -0
- data/core/tests/behavior/async_delete.rs +354 -0
- data/core/tests/behavior/async_list.rs +739 -0
- data/core/tests/behavior/async_presign.rs +175 -0
- data/core/tests/behavior/async_read.rs +871 -0
- data/core/tests/behavior/async_rename.rs +210 -0
- data/core/tests/behavior/async_stat.rs +628 -0
- data/core/tests/behavior/async_write.rs +819 -0
- data/core/tests/behavior/main.rs +78 -0
- data/core/tests/behavior/utils.rs +187 -0
- data/core/tests/data/normal_dir/.gitkeep +0 -0
- data/core/tests/data/normal_file.txt +1041 -0
- data/core/tests/data/special_dir !@#$%^&()_+-=;',/.gitkeep +0 -0
- data/core/tests/data/special_file !@#$%^&()_+-=;',.txt +1041 -0
- data/core/users.md +13 -0
- data/extconf.rb +24 -0
- data/lib/opendal.rb +25 -0
- data/lib/opendal_ruby/entry.rb +35 -0
- data/lib/opendal_ruby/io.rb +70 -0
- data/lib/opendal_ruby/metadata.rb +44 -0
- data/lib/opendal_ruby/operator.rb +29 -0
- data/lib/opendal_ruby/operator_info.rb +26 -0
- data/src/capability.rs +146 -0
- data/src/io.rs +464 -0
- data/src/lib.rs +63 -0
- data/src/lister.rs +141 -0
- data/src/metadata.rs +111 -0
- data/src/middlewares.rs +174 -0
- data/src/operator.rs +310 -0
- data/src/operator_info.rs +83 -0
- data/test/blocking_op_test.rb +112 -0
- data/test/capability_test.rb +42 -0
- data/test/io_test.rb +172 -0
- data/test/lister_test.rb +77 -0
- data/test/metadata_test.rb +78 -0
- data/test/middlewares_test.rb +46 -0
- data/test/operator_info_test.rb +35 -0
- data/test/test_helper.rb +36 -0
- metadata +857 -0
data/src/io.rs
ADDED
|
@@ -0,0 +1,464 @@
|
|
|
1
|
+
// Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
|
3
|
+
// distributed with this work for additional information
|
|
4
|
+
// regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
|
6
|
+
// "License"); you may not use this file except in compliance
|
|
7
|
+
// with the License. You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
|
12
|
+
// software distributed under the License is distributed on an
|
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
// KIND, either express or implied. See the License for the
|
|
15
|
+
// specific language governing permissions and limitations
|
|
16
|
+
// under the License.
|
|
17
|
+
|
|
18
|
+
#![allow(
|
|
19
|
+
rustdoc::broken_intra_doc_links,
|
|
20
|
+
reason = "YARD's syntax for documentation"
|
|
21
|
+
)]
|
|
22
|
+
#![allow(rustdoc::invalid_html_tags, reason = "YARD's syntax for documentation")]
|
|
23
|
+
#![allow(rustdoc::bare_urls, reason = "YARD's syntax for documentation")]
|
|
24
|
+
|
|
25
|
+
use std::cell::RefCell;
|
|
26
|
+
use std::io::BufRead;
|
|
27
|
+
use std::io::Read;
|
|
28
|
+
use std::io::Seek;
|
|
29
|
+
use std::io::SeekFrom;
|
|
30
|
+
use std::io::Write;
|
|
31
|
+
|
|
32
|
+
use magnus::io::FMode;
|
|
33
|
+
use magnus::method;
|
|
34
|
+
use magnus::prelude::*;
|
|
35
|
+
use magnus::scan_args::scan_args;
|
|
36
|
+
use magnus::Error;
|
|
37
|
+
use magnus::RHash;
|
|
38
|
+
use magnus::RModule;
|
|
39
|
+
use magnus::RString;
|
|
40
|
+
use magnus::Value;
|
|
41
|
+
|
|
42
|
+
use crate::*;
|
|
43
|
+
|
|
44
|
+
// `Io` is the rust implementation for `OpenDal::IO`. `Io` follows similar Ruby IO classes, such as:
|
|
45
|
+
// - IO
|
|
46
|
+
// - StringIO
|
|
47
|
+
//
|
|
48
|
+
// `Io` is not exactly an `IO` but is unidirectional (either `Reader` or `Writer`).
|
|
49
|
+
// TODO: implement encoding.
|
|
50
|
+
//
|
|
51
|
+
/// @yard
|
|
52
|
+
/// `OpenDal::IO` is similar to Ruby's `IO` and `StringIO` for accessing files.
|
|
53
|
+
///
|
|
54
|
+
/// You can't create an instance of `OpenDal::IO` except using {OpenDal::Operator#open}.
|
|
55
|
+
///
|
|
56
|
+
/// Constraints:
|
|
57
|
+
/// - Only available for reading and writing
|
|
58
|
+
/// - Writing doesn't support seek.
|
|
59
|
+
#[magnus::wrap(class = "OpenDal::IO", free_immediately, size)]
|
|
60
|
+
pub struct Io(RefCell<IoHandle>);
|
|
61
|
+
|
|
62
|
+
enum FileState {
|
|
63
|
+
Reader(ocore::blocking::StdReader),
|
|
64
|
+
Writer(ocore::blocking::StdWriter),
|
|
65
|
+
Closed,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
struct IoHandle {
|
|
69
|
+
state: FileState,
|
|
70
|
+
fmode: FMode,
|
|
71
|
+
#[allow(dead_code)]
|
|
72
|
+
external_encoding_name: Option<String>,
|
|
73
|
+
#[allow(dead_code)]
|
|
74
|
+
internal_encoding_name: Option<String>,
|
|
75
|
+
#[allow(dead_code)]
|
|
76
|
+
encoding_flags: i32,
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
pub fn format_io_error(ruby: &Ruby, err: std::io::Error) -> Error {
|
|
80
|
+
Error::new(ruby.exception_runtime_error(), err.to_string())
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
impl Io {
|
|
84
|
+
/// Creates a new `OpenDal::IO` object in Ruby.
|
|
85
|
+
///
|
|
86
|
+
/// See [`Operator::open`] for more information.
|
|
87
|
+
pub fn new(
|
|
88
|
+
ruby: &Ruby,
|
|
89
|
+
operator: ocore::blocking::Operator,
|
|
90
|
+
path: String,
|
|
91
|
+
mut mode: Value,
|
|
92
|
+
mut permission: Value,
|
|
93
|
+
kwargs: RHash,
|
|
94
|
+
) -> Result<Self, Error> {
|
|
95
|
+
let (_open_flags, fmode, encoding) =
|
|
96
|
+
ruby.io_extract_modeenc(&mut mode, &mut permission, &kwargs)?;
|
|
97
|
+
|
|
98
|
+
let state =
|
|
99
|
+
// Create reader if mode supports reading
|
|
100
|
+
if fmode.contains(FMode::READ) {
|
|
101
|
+
FileState::Reader(
|
|
102
|
+
operator
|
|
103
|
+
.reader(&path)
|
|
104
|
+
.map_err(|err| format_magnus_error(ruby, err))?
|
|
105
|
+
.into_std_read(..)
|
|
106
|
+
.map_err(|err| format_magnus_error(ruby, err))?,
|
|
107
|
+
)
|
|
108
|
+
} else if fmode.contains(FMode::WRITE) {
|
|
109
|
+
FileState::Writer(
|
|
110
|
+
operator
|
|
111
|
+
.writer(&path)
|
|
112
|
+
.map_err(|err| format_magnus_error(ruby, err))?
|
|
113
|
+
.into_std_write(),
|
|
114
|
+
)
|
|
115
|
+
} else {
|
|
116
|
+
return Err(Error::new(
|
|
117
|
+
ruby.exception_arg_error(),
|
|
118
|
+
"Invalid mode: must open for reading or writing",
|
|
119
|
+
));
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
Ok(Self(RefCell::new(IoHandle {
|
|
123
|
+
state,
|
|
124
|
+
fmode,
|
|
125
|
+
external_encoding_name: encoding.external.map(|e| e.to_string()),
|
|
126
|
+
internal_encoding_name: encoding.internal.map(|e| e.to_string()),
|
|
127
|
+
encoding_flags: encoding.flags,
|
|
128
|
+
})))
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/// @yard
|
|
132
|
+
/// @def binmode
|
|
133
|
+
/// Enables binary mode for the stream.
|
|
134
|
+
/// @return [nil]
|
|
135
|
+
/// @raise [IOError] when operate on a closed stream
|
|
136
|
+
fn binary_mode(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
|
|
137
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
138
|
+
if let FileState::Closed = handle.state {
|
|
139
|
+
return Err(Error::new(ruby.exception_io_error(), "closed stream"));
|
|
140
|
+
}
|
|
141
|
+
handle.fmode = FMode::new(handle.fmode.bits() | FMode::BINARY_MODE);
|
|
142
|
+
Ok(())
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/// @yard
|
|
146
|
+
/// @def binmode?
|
|
147
|
+
/// Returns if the stream is on binary mode.
|
|
148
|
+
/// @return [Boolean]
|
|
149
|
+
/// @raise [IOError] when operate on a closed stream
|
|
150
|
+
fn is_binary_mode(ruby: &Ruby, rb_self: &Self) -> Result<bool, Error> {
|
|
151
|
+
let handle = rb_self.0.borrow();
|
|
152
|
+
if let FileState::Closed = handle.state {
|
|
153
|
+
return Err(Error::new(ruby.exception_io_error(), "closed stream"));
|
|
154
|
+
}
|
|
155
|
+
Ok(handle.fmode.contains(FMode::BINARY_MODE))
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/// @yard
|
|
159
|
+
/// @def close
|
|
160
|
+
/// Close streams.
|
|
161
|
+
/// @return [nil]
|
|
162
|
+
fn close(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
|
|
163
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
164
|
+
if let FileState::Writer(writer) = &mut handle.state {
|
|
165
|
+
writer.close().map_err(|err| format_io_error(ruby, err))?;
|
|
166
|
+
}
|
|
167
|
+
handle.state = FileState::Closed;
|
|
168
|
+
Ok(())
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/// @yard
|
|
172
|
+
/// @def close_read
|
|
173
|
+
/// Closes the read stream.
|
|
174
|
+
/// @return [nil]
|
|
175
|
+
fn close_read(&self) -> Result<(), Error> {
|
|
176
|
+
let mut handle = self.0.borrow_mut();
|
|
177
|
+
if let FileState::Reader(_) = &handle.state {
|
|
178
|
+
handle.state = FileState::Closed;
|
|
179
|
+
}
|
|
180
|
+
Ok(())
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/// @yard
|
|
184
|
+
/// @def close_write
|
|
185
|
+
/// Closes the write stream.
|
|
186
|
+
/// @return [nil]
|
|
187
|
+
fn close_write(ruby: &Ruby, rb_self: &Self) -> Result<(), Error> {
|
|
188
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
189
|
+
if let FileState::Writer(writer) = &mut handle.state {
|
|
190
|
+
writer.close().map_err(|err| format_io_error(ruby, err))?;
|
|
191
|
+
handle.state = FileState::Closed;
|
|
192
|
+
}
|
|
193
|
+
Ok(())
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/// @yard
|
|
197
|
+
/// @def closed?
|
|
198
|
+
/// Returns if streams are closed.
|
|
199
|
+
/// @return [Boolean]
|
|
200
|
+
fn is_closed(&self) -> Result<bool, Error> {
|
|
201
|
+
let handle = self.0.borrow();
|
|
202
|
+
Ok(matches!(handle.state, FileState::Closed))
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/// @yard
|
|
206
|
+
/// @def closed_read?
|
|
207
|
+
/// Returns if the read stream is closed.
|
|
208
|
+
/// @return [Boolean]
|
|
209
|
+
fn is_closed_read(&self) -> Result<bool, Error> {
|
|
210
|
+
let handle = self.0.borrow();
|
|
211
|
+
Ok(!matches!(handle.state, FileState::Reader(_)))
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/// @yard
|
|
215
|
+
/// @def closed_write?
|
|
216
|
+
/// Returns if the write stream is closed.
|
|
217
|
+
/// @return [Boolean]
|
|
218
|
+
fn is_closed_write(&self) -> Result<bool, Error> {
|
|
219
|
+
let handle = self.0.borrow();
|
|
220
|
+
Ok(!matches!(handle.state, FileState::Writer(_)))
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
impl Io {
|
|
225
|
+
/// Reads data from the stream.
|
|
226
|
+
/// TODO:
|
|
227
|
+
/// - support encoding
|
|
228
|
+
///
|
|
229
|
+
/// @param size [Integer, nil] The maximum number of bytes to read. Reads all data when not provided.
|
|
230
|
+
/// @param buffer [String, nil] The output buffer to append to.
|
|
231
|
+
fn read(ruby: &Ruby, rb_self: &Self, args: &[Value]) -> Result<Option<bytes::Bytes>, Error> {
|
|
232
|
+
let args = scan_args::<(), (Option<Option<i64>>, Option<RString>), (), (), (), ()>(args)?;
|
|
233
|
+
let (option_size, mut option_output_buffer) = args.optional;
|
|
234
|
+
let size = option_size.unwrap_or_default(); // allow nil
|
|
235
|
+
|
|
236
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
237
|
+
|
|
238
|
+
if let FileState::Reader(reader) = &mut handle.state {
|
|
239
|
+
let buffer: Option<bytes::Bytes> = match size {
|
|
240
|
+
Some(size) => {
|
|
241
|
+
if size <= 0 {
|
|
242
|
+
return Err(Error::new(
|
|
243
|
+
ruby.exception_arg_error(),
|
|
244
|
+
format!("negative length {} given", size),
|
|
245
|
+
));
|
|
246
|
+
}
|
|
247
|
+
let mut bs = vec![0; size as usize];
|
|
248
|
+
let n = reader
|
|
249
|
+
.read(&mut bs)
|
|
250
|
+
.map_err(|err| format_io_error(ruby, err))?;
|
|
251
|
+
if n == 0 && size > 0 {
|
|
252
|
+
// when called at end of file, read(positive_integer) returns nil.
|
|
253
|
+
None
|
|
254
|
+
} else {
|
|
255
|
+
bs.truncate(n);
|
|
256
|
+
Some(bs.into())
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
None => {
|
|
260
|
+
let mut buffer = Vec::new();
|
|
261
|
+
reader
|
|
262
|
+
.read_to_end(&mut buffer)
|
|
263
|
+
.map_err(|err| format_io_error(ruby, err))?;
|
|
264
|
+
Some(buffer.into())
|
|
265
|
+
}
|
|
266
|
+
};
|
|
267
|
+
|
|
268
|
+
// when provided the buffer parameter, append read buffer
|
|
269
|
+
if let (Some(output_buffer), Some(inner)) =
|
|
270
|
+
(option_output_buffer.as_mut(), buffer.as_ref())
|
|
271
|
+
{
|
|
272
|
+
output_buffer.cat(inner);
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
Ok(buffer)
|
|
276
|
+
} else {
|
|
277
|
+
Err(Error::new(
|
|
278
|
+
ruby.exception_runtime_error(),
|
|
279
|
+
"I/O operation failed for reading on write-only file.",
|
|
280
|
+
))
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/// @yard
|
|
285
|
+
/// @def readline
|
|
286
|
+
/// Reads a single line from the stream.
|
|
287
|
+
/// @return [String]
|
|
288
|
+
// TODO: extend readline with parameters
|
|
289
|
+
fn readline(ruby: &Ruby, rb_self: &Self) -> Result<String, Error> {
|
|
290
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
291
|
+
|
|
292
|
+
if let FileState::Reader(reader) = &mut handle.state {
|
|
293
|
+
let mut buffer = String::new();
|
|
294
|
+
let size = reader
|
|
295
|
+
.read_line(&mut buffer)
|
|
296
|
+
.map_err(|err| format_io_error(ruby, err))?;
|
|
297
|
+
if size == 0 {
|
|
298
|
+
return Err(Error::new(
|
|
299
|
+
ruby.exception_eof_error(),
|
|
300
|
+
"end of file reached",
|
|
301
|
+
));
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
Ok(buffer)
|
|
305
|
+
} else {
|
|
306
|
+
Err(Error::new(
|
|
307
|
+
ruby.exception_runtime_error(),
|
|
308
|
+
"I/O operation failed for reading on write-only file.",
|
|
309
|
+
))
|
|
310
|
+
}
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
/// @yard
|
|
314
|
+
/// @def write(buffer)
|
|
315
|
+
/// Writes data to the stream.
|
|
316
|
+
/// @param buffer [String]
|
|
317
|
+
/// @return [Integer] the written byte size
|
|
318
|
+
fn write(ruby: &Ruby, rb_self: &Self, bs: String) -> Result<usize, Error> {
|
|
319
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
320
|
+
|
|
321
|
+
if let FileState::Writer(writer) = &mut handle.state {
|
|
322
|
+
let bytes_written = bs.len();
|
|
323
|
+
writer
|
|
324
|
+
.write_all(bs.as_bytes())
|
|
325
|
+
.map_err(|err| format_io_error(ruby, err))?;
|
|
326
|
+
Ok(bytes_written)
|
|
327
|
+
} else {
|
|
328
|
+
Err(Error::new(
|
|
329
|
+
ruby.exception_runtime_error(),
|
|
330
|
+
"I/O operation failed for writing on read-only file.",
|
|
331
|
+
))
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
impl Io {
|
|
337
|
+
/// @yard
|
|
338
|
+
/// @def seek(offset, whence)
|
|
339
|
+
/// Moves the file position based on the offset and whence.
|
|
340
|
+
/// @param offset [Integer] The position offset.
|
|
341
|
+
/// @param whence [Integer] The reference point:
|
|
342
|
+
/// - 0 = IO:SEEK_SET (Start)
|
|
343
|
+
/// - 1 = IO:SEEK_CUR (Current position)
|
|
344
|
+
/// - 2 = IO:SEEK_END (From the end)
|
|
345
|
+
///
|
|
346
|
+
/// @return [Integer] always 0 if the seek operation is successful
|
|
347
|
+
fn seek(ruby: &Ruby, rb_self: &Self, offset: i64, whence: u8) -> Result<u8, Error> {
|
|
348
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
349
|
+
|
|
350
|
+
if let FileState::Reader(reader) = &mut handle.state {
|
|
351
|
+
// Calculate the new position first
|
|
352
|
+
let new_reader_position = match whence {
|
|
353
|
+
0 => {
|
|
354
|
+
// SEEK_SET - absolute position
|
|
355
|
+
if offset < 0 {
|
|
356
|
+
return Err(Error::new(
|
|
357
|
+
ruby.exception_runtime_error(),
|
|
358
|
+
"Cannot seek to negative reader_position.",
|
|
359
|
+
));
|
|
360
|
+
}
|
|
361
|
+
offset as u64
|
|
362
|
+
}
|
|
363
|
+
1 => {
|
|
364
|
+
// SEEK_CUR - relative to current position
|
|
365
|
+
let position = reader
|
|
366
|
+
.stream_position()
|
|
367
|
+
.map_err(|err| format_io_error(ruby, err))?;
|
|
368
|
+
if offset < 0 && (-offset as u64) > position {
|
|
369
|
+
return Err(Error::new(
|
|
370
|
+
ruby.exception_runtime_error(),
|
|
371
|
+
"Cannot seek before start of stream.",
|
|
372
|
+
));
|
|
373
|
+
}
|
|
374
|
+
(position as i64 + offset) as u64
|
|
375
|
+
}
|
|
376
|
+
2 => {
|
|
377
|
+
// SEEK_END
|
|
378
|
+
let end_pos = reader
|
|
379
|
+
.seek(SeekFrom::End(0))
|
|
380
|
+
.map_err(|err| format_io_error(ruby, err))?;
|
|
381
|
+
if offset < 0 && (-offset as u64) > end_pos {
|
|
382
|
+
return Err(Error::new(
|
|
383
|
+
ruby.exception_runtime_error(),
|
|
384
|
+
"Cannot seek before start of stream.",
|
|
385
|
+
));
|
|
386
|
+
}
|
|
387
|
+
(end_pos as i64 + offset) as u64
|
|
388
|
+
}
|
|
389
|
+
_ => return Err(Error::new(ruby.exception_arg_error(), "invalid whence")),
|
|
390
|
+
};
|
|
391
|
+
|
|
392
|
+
let _ = reader.seek(std::io::SeekFrom::Start(new_reader_position));
|
|
393
|
+
} else {
|
|
394
|
+
return Err(Error::new(
|
|
395
|
+
ruby.exception_runtime_error(),
|
|
396
|
+
"Cannot seek from end on write-only stream.",
|
|
397
|
+
));
|
|
398
|
+
}
|
|
399
|
+
|
|
400
|
+
Ok(0)
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/// @yard
|
|
404
|
+
/// @def tell
|
|
405
|
+
/// Returns the current reader_position of the file pointer in the stream.
|
|
406
|
+
/// @return [Integer] the current reader_position in bytes
|
|
407
|
+
/// @raise [IOError] when cannot operate on the operation mode
|
|
408
|
+
fn tell(ruby: &Ruby, rb_self: &Self) -> Result<u64, Error> {
|
|
409
|
+
let mut handle = rb_self.0.borrow_mut();
|
|
410
|
+
|
|
411
|
+
match &mut handle.state {
|
|
412
|
+
FileState::Reader(reader) => Ok(reader
|
|
413
|
+
.stream_position()
|
|
414
|
+
.map_err(|err| format_io_error(ruby, err))?),
|
|
415
|
+
FileState::Writer(_) => Err(Error::new(
|
|
416
|
+
ruby.exception_runtime_error(),
|
|
417
|
+
"I/O operation failed for reading on write only file.",
|
|
418
|
+
)),
|
|
419
|
+
FileState::Closed => Err(Error::new(
|
|
420
|
+
ruby.exception_runtime_error(),
|
|
421
|
+
"I/O operation failed for tell on closed stream.",
|
|
422
|
+
)),
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
// TODO: consider implement:
|
|
427
|
+
// - lineno
|
|
428
|
+
// - set_lineno
|
|
429
|
+
// - getc
|
|
430
|
+
// - putc
|
|
431
|
+
// - gets
|
|
432
|
+
// - puts
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/// Defines the `OpenDal::IO` class in the given Ruby module and binds its methods.
|
|
436
|
+
///
|
|
437
|
+
/// This function uses Magnus's built-in Ruby thread-safety features to define the
|
|
438
|
+
/// `OpenDal::IO` class and its methods in the provided Ruby module (`gem_module`).
|
|
439
|
+
///
|
|
440
|
+
/// # Ruby Object Lifetime and Safety
|
|
441
|
+
///
|
|
442
|
+
/// Ruby objects can only exist in the Ruby heap and are tracked by Ruby's garbage collector (GC).
|
|
443
|
+
/// While we can allocate and store Ruby-related objects in the Rust heap, Magnus does not
|
|
444
|
+
/// automatically track such objects. Therefore, it is critical to work within Magnus's safety
|
|
445
|
+
/// guidelines when integrating Rust objects with Ruby. Read more in the Magnus documentation:
|
|
446
|
+
/// [Magnus Safety Documentation](https://github.com/matsadler/magnus#safety).
|
|
447
|
+
pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
|
|
448
|
+
let class = gem_module.define_class("IO", ruby.class_object())?;
|
|
449
|
+
class.define_method("binmode", method!(Io::binary_mode, 0))?;
|
|
450
|
+
class.define_method("binmode?", method!(Io::is_binary_mode, 0))?;
|
|
451
|
+
class.define_method("close", method!(Io::close, 0))?;
|
|
452
|
+
class.define_method("close_read", method!(Io::close_read, 0))?;
|
|
453
|
+
class.define_method("close_write", method!(Io::close_write, 0))?;
|
|
454
|
+
class.define_method("closed?", method!(Io::is_closed, 0))?;
|
|
455
|
+
class.define_method("closed_read?", method!(Io::is_closed_read, 0))?;
|
|
456
|
+
class.define_method("closed_write?", method!(Io::is_closed_write, 0))?;
|
|
457
|
+
class.define_method("read", method!(Io::read, -1))?;
|
|
458
|
+
class.define_method("write", method!(Io::write, 1))?;
|
|
459
|
+
class.define_method("readline", method!(Io::readline, 0))?;
|
|
460
|
+
class.define_method("seek", method!(Io::seek, 2))?;
|
|
461
|
+
class.define_method("tell", method!(Io::tell, 0))?;
|
|
462
|
+
|
|
463
|
+
Ok(())
|
|
464
|
+
}
|
data/src/lib.rs
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
|
3
|
+
// distributed with this work for additional information
|
|
4
|
+
// regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
|
6
|
+
// "License"); you may not use this file except in compliance
|
|
7
|
+
// with the License. You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
|
12
|
+
// software distributed under the License is distributed on an
|
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
// KIND, either express or implied. See the License for the
|
|
15
|
+
// specific language governing permissions and limitations
|
|
16
|
+
// under the License.
|
|
17
|
+
|
|
18
|
+
use std::sync::LazyLock;
|
|
19
|
+
|
|
20
|
+
use magnus::function;
|
|
21
|
+
use magnus::Error;
|
|
22
|
+
use magnus::Module;
|
|
23
|
+
use magnus::Ruby;
|
|
24
|
+
|
|
25
|
+
// We will use `ocore::` to represents opendal rust core functionalities.
|
|
26
|
+
// This convention aligns with the Python binding.
|
|
27
|
+
pub use ::opendal as ocore;
|
|
28
|
+
|
|
29
|
+
mod capability;
|
|
30
|
+
mod io;
|
|
31
|
+
mod lister;
|
|
32
|
+
mod metadata;
|
|
33
|
+
mod middlewares;
|
|
34
|
+
mod operator;
|
|
35
|
+
mod operator_info;
|
|
36
|
+
|
|
37
|
+
static RUNTIME: LazyLock<tokio::runtime::Runtime> = LazyLock::new(|| {
|
|
38
|
+
tokio::runtime::Builder::new_multi_thread()
|
|
39
|
+
.enable_all()
|
|
40
|
+
.build()
|
|
41
|
+
.unwrap()
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
pub fn format_magnus_error(ruby: &Ruby, err: ocore::Error) -> Error {
|
|
45
|
+
Error::new(ruby.exception_runtime_error(), err.to_string())
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/// Apache OpenDAL™ Ruby binding
|
|
49
|
+
#[magnus::init]
|
|
50
|
+
fn init(ruby: &Ruby) -> Result<(), Error> {
|
|
51
|
+
let gem_module = ruby.define_module("OpenDal")?;
|
|
52
|
+
let _ = operator::include(ruby, &gem_module);
|
|
53
|
+
let _ = metadata::include(ruby, &gem_module);
|
|
54
|
+
let _ = capability::include(ruby, &gem_module);
|
|
55
|
+
let _ = io::include(ruby, &gem_module);
|
|
56
|
+
let _ = lister::include(ruby, &gem_module);
|
|
57
|
+
let _ = operator_info::include(ruby, &gem_module);
|
|
58
|
+
|
|
59
|
+
let middleware_module = gem_module.define_module("Middleware")?;
|
|
60
|
+
let _ = middlewares::include(ruby, &middleware_module);
|
|
61
|
+
|
|
62
|
+
Ok(())
|
|
63
|
+
}
|
data/src/lister.rs
ADDED
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
// Licensed to the Apache Software Foundation (ASF) under one
|
|
2
|
+
// or more contributor license agreements. See the NOTICE file
|
|
3
|
+
// distributed with this work for additional information
|
|
4
|
+
// regarding copyright ownership. The ASF licenses this file
|
|
5
|
+
// to you under the Apache License, Version 2.0 (the
|
|
6
|
+
// "License"); you may not use this file except in compliance
|
|
7
|
+
// with the License. You may obtain a copy of the License at
|
|
8
|
+
//
|
|
9
|
+
// http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
//
|
|
11
|
+
// Unless required by applicable law or agreed to in writing,
|
|
12
|
+
// software distributed under the License is distributed on an
|
|
13
|
+
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
|
14
|
+
// KIND, either express or implied. See the License for the
|
|
15
|
+
// specific language governing permissions and limitations
|
|
16
|
+
// under the License.
|
|
17
|
+
|
|
18
|
+
#![allow(
|
|
19
|
+
rustdoc::broken_intra_doc_links,
|
|
20
|
+
reason = "YARD's syntax for documentation"
|
|
21
|
+
)]
|
|
22
|
+
#![allow(rustdoc::invalid_html_tags, reason = "YARD's syntax for documentation")]
|
|
23
|
+
#![allow(rustdoc::bare_urls, reason = "YARD's syntax for documentation")]
|
|
24
|
+
|
|
25
|
+
use std::sync::Arc;
|
|
26
|
+
use std::sync::Mutex;
|
|
27
|
+
|
|
28
|
+
use magnus::block::Yield;
|
|
29
|
+
|
|
30
|
+
use magnus::method;
|
|
31
|
+
use magnus::prelude::*;
|
|
32
|
+
use magnus::Error;
|
|
33
|
+
use magnus::RModule;
|
|
34
|
+
use magnus::Ruby;
|
|
35
|
+
|
|
36
|
+
use crate::metadata::Metadata;
|
|
37
|
+
use crate::*;
|
|
38
|
+
|
|
39
|
+
/// @yard
|
|
40
|
+
/// Entry returned by Lister to represent a path and it's relative metadata.
|
|
41
|
+
#[magnus::wrap(class = "OpenDal::Entry", free_immediately, size)]
|
|
42
|
+
pub struct Entry(ocore::Entry);
|
|
43
|
+
|
|
44
|
+
impl Entry {
|
|
45
|
+
/// @yard
|
|
46
|
+
/// @def path
|
|
47
|
+
/// Gets the path of entry. Path is relative to operator's root.
|
|
48
|
+
///
|
|
49
|
+
/// Only valid in current operator.
|
|
50
|
+
///
|
|
51
|
+
/// If this entry is a dir, `path` MUST end with `/`
|
|
52
|
+
/// Otherwise, `path` MUST NOT end with `/`.
|
|
53
|
+
/// @return [String]
|
|
54
|
+
fn path(&self) -> Result<&str, Error> {
|
|
55
|
+
Ok(self.0.path())
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/// @yard
|
|
59
|
+
/// @def name
|
|
60
|
+
/// Gets the name of entry. Name is the last segment of path.
|
|
61
|
+
///
|
|
62
|
+
/// If this entry is a dir, `name` MUST end with `/`
|
|
63
|
+
/// Otherwise, `name` MUST NOT end with `/`.
|
|
64
|
+
/// @return [String]
|
|
65
|
+
fn name(&self) -> Result<&str, Error> {
|
|
66
|
+
Ok(self.0.name())
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/// @yard
|
|
70
|
+
/// @def metadata
|
|
71
|
+
/// Fetches the metadata of this entry.
|
|
72
|
+
/// @return [Metadata]
|
|
73
|
+
fn metadata(&self) -> Result<Metadata, Error> {
|
|
74
|
+
Ok(Metadata::new(self.0.metadata().clone()))
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/// @yard
|
|
79
|
+
/// Represents the result when list a directory
|
|
80
|
+
///
|
|
81
|
+
/// This class is an enumerable.
|
|
82
|
+
///
|
|
83
|
+
/// # Safety
|
|
84
|
+
///
|
|
85
|
+
/// `Lister` is thread-safe.
|
|
86
|
+
#[magnus::wrap(class = "OpenDal::Lister", free_immediately, size)]
|
|
87
|
+
pub struct Lister(Arc<Mutex<ocore::blocking::Lister>>);
|
|
88
|
+
|
|
89
|
+
impl Iterator for Lister {
|
|
90
|
+
type Item = Entry;
|
|
91
|
+
|
|
92
|
+
fn next(&mut self) -> Option<Self::Item> {
|
|
93
|
+
// assumes low contention. also we want an entry eventually
|
|
94
|
+
if let Ok(mut inner) = self.0.lock() {
|
|
95
|
+
match inner.next() {
|
|
96
|
+
Some(Ok(entry)) => Some(Entry(entry)),
|
|
97
|
+
_ => None,
|
|
98
|
+
}
|
|
99
|
+
} else {
|
|
100
|
+
None
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
impl Lister {
|
|
106
|
+
/// Creates a new blocking Lister.
|
|
107
|
+
pub fn new(inner: ocore::blocking::Lister) -> Self {
|
|
108
|
+
Self(Arc::new(Mutex::new(inner)))
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/// @yard
|
|
112
|
+
/// @def each
|
|
113
|
+
/// Returns the next element.
|
|
114
|
+
/// @return [Entry]
|
|
115
|
+
fn each(&self) -> Result<Yield<Lister>, Error> {
|
|
116
|
+
// Magnus handles yielding to Ruby using an unsafe internal function,
|
|
117
|
+
// so we don’t manage the actual iteration loop ourselves.
|
|
118
|
+
//
|
|
119
|
+
// Since Ruby controls when values are pulled from the iterator,
|
|
120
|
+
// and could potentially call `each` from multiple threads or fibers,
|
|
121
|
+
// we wrap the underlying lister in `Arc<Mutex<_>>` to ensure thread safety.
|
|
122
|
+
//
|
|
123
|
+
// Multi-threaded iteration is rare in Ruby, but this design ensures thread safety.
|
|
124
|
+
Ok(Yield::Iter(Lister(self.0.clone())))
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
pub fn include(ruby: &Ruby, gem_module: &RModule) -> Result<(), Error> {
|
|
129
|
+
let entry_class = gem_module.define_class("Entry", ruby.class_object())?;
|
|
130
|
+
entry_class.define_method("path", method!(Entry::path, 0))?;
|
|
131
|
+
entry_class.define_method("name", method!(Entry::name, 0))?;
|
|
132
|
+
entry_class.define_method("metadata", method!(Entry::metadata, 0))?;
|
|
133
|
+
|
|
134
|
+
let lister_class = gem_module.define_class("Lister", ruby.class_object())?;
|
|
135
|
+
lister_class
|
|
136
|
+
.include_module(ruby.module_enumerable())
|
|
137
|
+
.map_err(|err| Error::new(ruby.exception_runtime_error(), err.to_string()))?;
|
|
138
|
+
lister_class.define_method("each", method!(Lister::each, 0))?;
|
|
139
|
+
|
|
140
|
+
Ok(())
|
|
141
|
+
}
|