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
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# OpenDAL vs object_store
|
|
2
|
+
|
|
3
|
+
> NOTE: This document is written by OpenDAL's maintainers and not reviewed by
|
|
4
|
+
> object_store's maintainers. So it could not be very objective.
|
|
5
|
+
|
|
6
|
+
## About object_store
|
|
7
|
+
|
|
8
|
+
[object_store](https://crates.io/crates/object_store) is
|
|
9
|
+
|
|
10
|
+
> A focused, easy to use, idiomatic, high performance, `async` object store library interacting with object stores.
|
|
11
|
+
|
|
12
|
+
It was initially developed for [InfluxDB IOx](https://github.com/influxdata/influxdb_iox/) and later split out and donated to [Apache Arrow](https://arrow.apache.org/).
|
|
13
|
+
|
|
14
|
+
## Similarities
|
|
15
|
+
|
|
16
|
+
### Language
|
|
17
|
+
|
|
18
|
+
Yes, of course. Both `opendal` and `object_store` are developed in [Rust](https://www.rust-lang.org/), a language empowering everyone to build reliable and efficient software.
|
|
19
|
+
|
|
20
|
+
### License
|
|
21
|
+
|
|
22
|
+
Both `opendal` and `object_store` are licensed under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0).
|
|
23
|
+
|
|
24
|
+
### Owner
|
|
25
|
+
|
|
26
|
+
`object_store` is a part of `Apache Arrow` which means it's hosted and maintained by the [Apache Software Foundation](https://www.apache.org/).
|
|
27
|
+
|
|
28
|
+
`opendal` is now hosted by the [Apache Software Foundation](https://www.apache.org/) also.
|
|
29
|
+
|
|
30
|
+
### Domain
|
|
31
|
+
|
|
32
|
+
Both `opendal` and `object_store` can be used to access data stored on object storage services. The primary users of those projects are both cloud-native databases too:
|
|
33
|
+
|
|
34
|
+
- `opendal` is mainly used by:
|
|
35
|
+
- [databend](https://github.com/datafuselabs/databend): A modern Elasticity and Performance cloud data warehouse
|
|
36
|
+
- [GreptimeDB](https://github.com/GreptimeTeam/greptimedb): An open-source, cloud-native, distributed time-series database.
|
|
37
|
+
- [mozilla/sccache](https://github.com/mozilla/sccache/): sccache is ccache with cloud storage
|
|
38
|
+
- [risingwave](https://github.com/risingwavelabs/risingwave): A Distributed SQL Database for Stream Processing
|
|
39
|
+
- [Vector](https://github.com/vectordotdev/vector): A high-performance observability data pipeline.
|
|
40
|
+
- `object_store` is mainly used by:
|
|
41
|
+
- [datafusion](https://github.com/apache/arrow-datafusion): Apache Arrow DataFusion SQL Query Engine
|
|
42
|
+
- [Influxdb IOx](https://github.com/influxdata/influxdb_iox/): The new core of InfluxDB is written in Rust on top of Apache Arrow.
|
|
43
|
+
|
|
44
|
+
## Differences
|
|
45
|
+
|
|
46
|
+
### Vision
|
|
47
|
+
|
|
48
|
+
`opendal` is Open Data Access Layer that accesses data freely, painlessly, and efficiently. `object_store` is more focused on async object store support.
|
|
49
|
+
|
|
50
|
+
You will see the different visions lead to very different routes.
|
|
51
|
+
|
|
52
|
+
### Design
|
|
53
|
+
|
|
54
|
+
`object_store` exposed a trait called [`ObjectStore`](https://docs.rs/object_store/latest/object_store/trait.ObjectStore.html) to users.
|
|
55
|
+
|
|
56
|
+
Users need to build a `dyn ObjectStore` and operate on it directly:
|
|
57
|
+
|
|
58
|
+
```rust
|
|
59
|
+
let object_store: Arc<dyn ObjectStore> = Arc::new(get_object_store());
|
|
60
|
+
let path: Path = "data/file01.parquet".try_into()?;
|
|
61
|
+
let stream = object_store
|
|
62
|
+
.get(&path)
|
|
63
|
+
.await?
|
|
64
|
+
.into_stream();
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
`opendal` has a similar trait called [`Access`][crate::raw::Access]
|
|
68
|
+
|
|
69
|
+
But `opendal` don't expose this trait to end users directly. Instead, `opendal` expose a new struct called [`Operator`][crate::Operator] and builds public API on it.
|
|
70
|
+
|
|
71
|
+
```rust
|
|
72
|
+
let op: Operator = Operator::from_env(Scheme::S3)?;
|
|
73
|
+
let r = op.reader("data/file01.parquet").await?;
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### Interception
|
|
77
|
+
|
|
78
|
+
Both `object_store` and `opendal` provide a mechanism to intercept operations.
|
|
79
|
+
|
|
80
|
+
`object_store` called `Adapters`:
|
|
81
|
+
|
|
82
|
+
```rust
|
|
83
|
+
let object_store = ThrottledStore::new(get_object_store(), ThrottleConfig::default())
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
`opendal` called [`Layer`](crate::raw::Layer):
|
|
87
|
+
|
|
88
|
+
```rust
|
|
89
|
+
let op = op.layer(TracingLayer).layer(MetricsLayer);
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
At the time of writing:
|
|
93
|
+
|
|
94
|
+
object_store (`v0.5.0`) supports:
|
|
95
|
+
|
|
96
|
+
- ThrottleStore: Rate Throttling
|
|
97
|
+
- LimitStore: Concurrent Request Limit
|
|
98
|
+
|
|
99
|
+
opendal supports:
|
|
100
|
+
|
|
101
|
+
- ImmutableIndexLayer: immutable in-memory index.
|
|
102
|
+
- LoggingLayer: logging.
|
|
103
|
+
- MetadataCacheLayer: metadata cache.
|
|
104
|
+
- ContentCacheLayer: content data cache.
|
|
105
|
+
- MetricsLayer: metrics
|
|
106
|
+
- RetryLayer: retry
|
|
107
|
+
- SubdirLayer: Allow switch directory without changing original operator.
|
|
108
|
+
- TracingLayer: tracing
|
|
109
|
+
|
|
110
|
+
### Services
|
|
111
|
+
|
|
112
|
+
`opendal` and `object_store` have different visions, so they have other services support:
|
|
113
|
+
|
|
114
|
+
| service | opendal | object_store |
|
|
115
|
+
|---------|-----------------|-----------------------------------------|
|
|
116
|
+
| azblob | Y | Y |
|
|
117
|
+
| fs | Y | Y |
|
|
118
|
+
| ftp | Y | N |
|
|
119
|
+
| gcs | Y | Y |
|
|
120
|
+
| hdfs | Y | Y *(via [datafusion-objectstore-hdfs])* |
|
|
121
|
+
| http | Y *(read only)* | N |
|
|
122
|
+
| ipfs | Y *(read only)* | N |
|
|
123
|
+
| ipmfs | Y | N |
|
|
124
|
+
| memory | Y | Y |
|
|
125
|
+
| obs | Y | N |
|
|
126
|
+
| s3 | Y | Y |
|
|
127
|
+
|
|
128
|
+
opendal has an idea called [`Capability`][crate::Capability], so it's services may have different capability sets. For example, opendal's `http` and `ipfs` are read only.
|
|
129
|
+
|
|
130
|
+
### Features
|
|
131
|
+
|
|
132
|
+
`opendal` and `object_store` have different visions, so they have different feature sets:
|
|
133
|
+
|
|
134
|
+
| opendal | object_store | notes |
|
|
135
|
+
|-----------|----------------------|----------------------------------------------|
|
|
136
|
+
| metadata | - | get some metadata from underlying storage |
|
|
137
|
+
| create | put | - |
|
|
138
|
+
| read | get | - |
|
|
139
|
+
| read | get_range | - |
|
|
140
|
+
| - | get_ranges | opendal doesn't support read multiple ranges |
|
|
141
|
+
| write | put | - |
|
|
142
|
+
| stat | head | - |
|
|
143
|
+
| delete | delete | - |
|
|
144
|
+
| - | list | opendal doesn't support list with prefix |
|
|
145
|
+
| list | list_with_delimiter | - |
|
|
146
|
+
| - | copy | - |
|
|
147
|
+
| - | copy_if_not_exists | - |
|
|
148
|
+
| - | rename | - |
|
|
149
|
+
| - | rename_if_not_exists | - |
|
|
150
|
+
| presign | - | get a presign URL of object |
|
|
151
|
+
| multipart | multipart | both support, but API is different |
|
|
152
|
+
| blocking | - | opendal supports blocking API |
|
|
153
|
+
|
|
154
|
+
## Demo show
|
|
155
|
+
|
|
156
|
+
The most straightforward complete demo how to read a file from s3:
|
|
157
|
+
|
|
158
|
+
`opendal`
|
|
159
|
+
|
|
160
|
+
```rust
|
|
161
|
+
let mut builder = S3::default();
|
|
162
|
+
builder.bucket("example");
|
|
163
|
+
builder.access_key_id("access_key_id");
|
|
164
|
+
builder.secret_access_key("secret_access_key");
|
|
165
|
+
|
|
166
|
+
let store = Operator::new(builder)?.finish();
|
|
167
|
+
let r = store.reader("data.parquet").await?;
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
`object_store`
|
|
171
|
+
|
|
172
|
+
```rust
|
|
173
|
+
let mut builder = AmazonS3Builder::new()
|
|
174
|
+
.with_bucket_name("example")
|
|
175
|
+
.with_access_key_id("access_key_id")
|
|
176
|
+
.with_secret_access_key("secret_access_key");
|
|
177
|
+
|
|
178
|
+
let store = Arc::new(builder.build()?);
|
|
179
|
+
let path: Path = "data.parquet".try_into().unwrap();
|
|
180
|
+
let stream = store.get(&path).await()?.into_stream();
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
[datafusion-objectstore-hdfs]: https://github.com/datafusion-contrib/datafusion-objectstore-hdfs/
|
|
@@ -0,0 +1,135 @@
|
|
|
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
|
+
//! The core concepts of OpenDAL's public API.
|
|
19
|
+
//!
|
|
20
|
+
//! OpenDAL provides a unified abstraction that helps developers access all storage services.
|
|
21
|
+
//!
|
|
22
|
+
//! There are two core concepts in OpenDAL:
|
|
23
|
+
//!
|
|
24
|
+
//! - [`Builder`]: Builder accepts a series of parameters to set up an instance of underlying services.
|
|
25
|
+
//! You can adjust the behaviour of underlying services with these parameters.
|
|
26
|
+
//! - [`Operator`]: Developer can access underlying storage services with manipulating one Operator.
|
|
27
|
+
//! The Operator is a delegate for underlying implementation detail, and provides one unified access interface,
|
|
28
|
+
//! including `read`, `write`, `list` and so on.
|
|
29
|
+
//!
|
|
30
|
+
//! If you are interested in internal implementation details, please have a look at [`internals`][super::internals].
|
|
31
|
+
//!
|
|
32
|
+
//! # Builder
|
|
33
|
+
//!
|
|
34
|
+
//! Let's start with [`Builder`].
|
|
35
|
+
//!
|
|
36
|
+
//! A `Builder` is a trait that is implemented by the underlying services. We can use a `Builder` to configure and create a service.
|
|
37
|
+
//! Developer can only create one service via Builder, in other words, Builder is the only public API provided by services.
|
|
38
|
+
//! And other detailed implementation will be hidden.
|
|
39
|
+
//!
|
|
40
|
+
//! ```text
|
|
41
|
+
//! ┌───────────┐ ┌───────────┐
|
|
42
|
+
//! │ │ build() │ │
|
|
43
|
+
//! │ Builder ├────────────────►│ Service │
|
|
44
|
+
//! │ │ │ │
|
|
45
|
+
//! └───────────┘ └───────────┘
|
|
46
|
+
//! ```
|
|
47
|
+
//!
|
|
48
|
+
//! All [`Builder`] provided by OpenDAL is under [`services`][crate::services], we can refer to them like `opendal::services::S3`.
|
|
49
|
+
//! By right the builder will be named like `OneServiceBuilder`, but usually we will export it to public with renaming it as one
|
|
50
|
+
//! general name. For example, we will rename `S3Builder` to `S3` and developer will use `S3` finally.
|
|
51
|
+
//!
|
|
52
|
+
//! For example:
|
|
53
|
+
//!
|
|
54
|
+
//! ```no_run
|
|
55
|
+
//! use opendal::services::S3;
|
|
56
|
+
//!
|
|
57
|
+
//! let mut builder = S3::default();
|
|
58
|
+
//! builder.bucket("example");
|
|
59
|
+
//! builder.root("/path/to/file");
|
|
60
|
+
//! ```
|
|
61
|
+
//!
|
|
62
|
+
//! # Operator
|
|
63
|
+
//! The [`Operator`] is a delegate for Service, the underlying implementation detail that implements [`Access`][crate::raw::Access],
|
|
64
|
+
//! and it also provides one unified access interface.
|
|
65
|
+
//! It will hold one reference of Service with its all generic types erased by OpenDAL,
|
|
66
|
+
//! which is the reason why we say the Operator is the delegate of one Service.
|
|
67
|
+
//!
|
|
68
|
+
//! ```text
|
|
69
|
+
//! ┌────────────────────┐
|
|
70
|
+
//! │ Operator │
|
|
71
|
+
//! │ │delegate │
|
|
72
|
+
//! ┌─────────┐ build │ ▼ │ rely on ┌─────────────────────┐
|
|
73
|
+
//! │ Builder ├───────┼──►┌────────────┐ │◄────────┤ business logic code │
|
|
74
|
+
//! └─────────┘ │ │ Service │ │ └─────────────────────┘
|
|
75
|
+
//! └───┴────────────┴───┘
|
|
76
|
+
//! ```
|
|
77
|
+
//!
|
|
78
|
+
//! `Operator` can be built from `Builder`:
|
|
79
|
+
//!
|
|
80
|
+
//! ```no_run
|
|
81
|
+
//! # use opendal::Result;
|
|
82
|
+
//! use opendal::services::S3;
|
|
83
|
+
//! use opendal::Operator;
|
|
84
|
+
//!
|
|
85
|
+
//! # fn test() -> Result<()> {
|
|
86
|
+
//! let mut builder = S3::default();
|
|
87
|
+
//! builder.bucket("example");
|
|
88
|
+
//! builder.root("/path/to/file");
|
|
89
|
+
//!
|
|
90
|
+
//! let op = Operator::new(builder)?.finish();
|
|
91
|
+
//! # Ok(())
|
|
92
|
+
//! # }
|
|
93
|
+
//! ```
|
|
94
|
+
//!
|
|
95
|
+
//! - `Operator` has it's internal `Arc`, so it's **cheap** to clone it.
|
|
96
|
+
//! - `Operator` doesn't have generic parameters or lifetimes, so it's **easy** to use it everywhere.
|
|
97
|
+
//! - `Operator` implements `Send` and `Sync`, so it's **safe** to send it between threads.
|
|
98
|
+
//!
|
|
99
|
+
//! After get an `Operator`, we can do operations on different paths.
|
|
100
|
+
//!
|
|
101
|
+
//!
|
|
102
|
+
//! ```text
|
|
103
|
+
//! ┌──────────────┐
|
|
104
|
+
//! ┌────────►│ read("abc") │
|
|
105
|
+
//! │ └──────────────┘
|
|
106
|
+
//! ┌───────────┐ │
|
|
107
|
+
//! │ Operator │ │ ┌──────────────┐
|
|
108
|
+
//! │ ┌───────┐ ├────┼────────►│ write("def") │
|
|
109
|
+
//! │ │Service│ │ │ └──────────────┘
|
|
110
|
+
//! └─┴───────┴─┘ │
|
|
111
|
+
//! │ ┌──────────────┐
|
|
112
|
+
//! └────────►│ list("ghi/") │
|
|
113
|
+
//! └──────────────┘
|
|
114
|
+
//! ```
|
|
115
|
+
//!
|
|
116
|
+
//! We can read data with given path in this way:
|
|
117
|
+
//!
|
|
118
|
+
//! ```no_run
|
|
119
|
+
//! # use opendal::Result;
|
|
120
|
+
//! use opendal::services::S3;
|
|
121
|
+
//! use opendal::Operator;
|
|
122
|
+
//!
|
|
123
|
+
//! # async fn test() -> Result<()> {
|
|
124
|
+
//! let mut builder = S3::default();
|
|
125
|
+
//! builder.bucket("example");
|
|
126
|
+
//! builder.root("/path/to/file");
|
|
127
|
+
//!
|
|
128
|
+
//! let op = Operator::new(builder)?.finish();
|
|
129
|
+
//! let bs: Vec<u8> = op.read("abc").await?;
|
|
130
|
+
//! # Ok(())
|
|
131
|
+
//! # }
|
|
132
|
+
//! ```
|
|
133
|
+
//!
|
|
134
|
+
//! [`Builder`]: crate::Builder
|
|
135
|
+
//! [`Operator`]: crate::Operator
|
|
@@ -0,0 +1,306 @@
|
|
|
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
|
+
//! The internal implementation details of [`Access`].
|
|
19
|
+
//!
|
|
20
|
+
//! [`Access`] is the core trait of OpenDAL's raw API. We operate
|
|
21
|
+
//! underlying storage services via APIs provided by [`Access`].
|
|
22
|
+
//!
|
|
23
|
+
//! # Introduction
|
|
24
|
+
//!
|
|
25
|
+
//! [`Access`] can be split in the following parts:
|
|
26
|
+
//!
|
|
27
|
+
//! ```ignore
|
|
28
|
+
//! // <----------Trait Bound-------------->
|
|
29
|
+
//! pub trait Access: Send + Sync + Debug + Unpin + 'static {
|
|
30
|
+
//! type Reader: oio::Read; // --+
|
|
31
|
+
//! type Writer: oio::Write; // +--> Associated Type
|
|
32
|
+
//! type Lister: oio::List; // +
|
|
33
|
+
//! type Deleter: oio::Delete; // --+
|
|
34
|
+
//!
|
|
35
|
+
//! // APIs
|
|
36
|
+
//! fn info(&self) -> Arc<AccessorInfo>;
|
|
37
|
+
//! fn create_dir(
|
|
38
|
+
//! &self,
|
|
39
|
+
//! path: &str,
|
|
40
|
+
//! args: OpCreateDir,
|
|
41
|
+
//! ) -> impl core::future::Future<Output = Result<RpCreateDir>> + MaybeSend;
|
|
42
|
+
//! }
|
|
43
|
+
//! ```
|
|
44
|
+
//!
|
|
45
|
+
//! Let's go deep into [`Access`] line by line.
|
|
46
|
+
//!
|
|
47
|
+
//! ## Trait Bound
|
|
48
|
+
//!
|
|
49
|
+
//! First we will read the declare of [`Access`] trait:
|
|
50
|
+
//!
|
|
51
|
+
//! ```ignore
|
|
52
|
+
//! pub trait Access: Send + Sync + Debug + Unpin + 'static {}
|
|
53
|
+
//! ```
|
|
54
|
+
//!
|
|
55
|
+
//! There are many trait boundings here. For now, [`Access`] requires the following bound:
|
|
56
|
+
//!
|
|
57
|
+
//! - [`Send`]: Allow user to send between threads without extra wrapper.
|
|
58
|
+
//! - [`Sync`]: Allow user to sync between threads without extra lock.
|
|
59
|
+
//! - [`Debug`][std::fmt::Debug]: Allow users to print underlying debug information of accessor.
|
|
60
|
+
//! - [`Unpin`]: Make sure `Access` can be safely moved after being pinned, so users don't need to `Pin<Box<A>>`.
|
|
61
|
+
//! - `'static`: Make sure `Access` is not a short-time reference, allow users to use `Access` in closures and futures without playing with lifetime.
|
|
62
|
+
//!
|
|
63
|
+
//! Implementer of `Access` should take care of the following things:
|
|
64
|
+
//!
|
|
65
|
+
//! - Implement `Debug` for backend, but don't leak credentials.
|
|
66
|
+
//! - Make sure the backend is `Send` and `Sync`, wrap the internal struct with `Arc<Mutex<T>>` if necessary.
|
|
67
|
+
//!
|
|
68
|
+
//! ## Associated Type
|
|
69
|
+
//!
|
|
70
|
+
//! The first block of [`Access`] trait is our associated types. We
|
|
71
|
+
//! require implementers to specify the type to be returned, thus avoiding
|
|
72
|
+
//! the additional overhead of dynamic dispatch.
|
|
73
|
+
//!
|
|
74
|
+
//! [`Access`] has four associated types so far:
|
|
75
|
+
//!
|
|
76
|
+
//! - `Reader`: reader returned by `read` operation.
|
|
77
|
+
//! - `Writer`: writer returned by `write` operation.
|
|
78
|
+
//! - `Lister`: lister returned by `list` operation.
|
|
79
|
+
//! - `Deleter`: deleter returned by `delete` operation.
|
|
80
|
+
//!
|
|
81
|
+
//! Implementer of `Access` should take care the following things:
|
|
82
|
+
//!
|
|
83
|
+
//! - OpenDAL will erase those type at the final stage of Operator building. Please don't return dynamic trait object like `oio::Reader`.
|
|
84
|
+
//! - Use `()` as type if the operation is not supported.
|
|
85
|
+
//!
|
|
86
|
+
//! ## API Style
|
|
87
|
+
//!
|
|
88
|
+
//! Every API of [`Access`] follows the same style:
|
|
89
|
+
//!
|
|
90
|
+
//! - All APIs have a unique [`Operation`] and [`Capability`]
|
|
91
|
+
//! - All APIs are orthogonal and do not overlap with each other
|
|
92
|
+
//! - Most APIs accept `path` and `OpXxx`, and returns `RpXxx`.
|
|
93
|
+
//! - Most APIs have `async` and `blocking` variants, they share the same semantics but may have different underlying implementations.
|
|
94
|
+
//!
|
|
95
|
+
//! [`Access`] can declare their capabilities via [`AccessorInfo`]'s `set_native_capability`:
|
|
96
|
+
//!
|
|
97
|
+
//! ```ignore
|
|
98
|
+
//! impl Access for MyBackend {
|
|
99
|
+
//! fn info(&self) -> Arc<AccessorInfo> {
|
|
100
|
+
//! let am = AccessorInfo::default();
|
|
101
|
+
//! am.set_native_capability(
|
|
102
|
+
//! Capability {
|
|
103
|
+
//! read: true,
|
|
104
|
+
//! write: true,
|
|
105
|
+
//! ..Default::default()
|
|
106
|
+
//! });
|
|
107
|
+
//!
|
|
108
|
+
//! am.into()
|
|
109
|
+
//! }
|
|
110
|
+
//! }
|
|
111
|
+
//! ```
|
|
112
|
+
//!
|
|
113
|
+
//! Now that you have mastered [`Access`], let's go and implement our own backend!
|
|
114
|
+
//!
|
|
115
|
+
//! # Tutorial
|
|
116
|
+
//!
|
|
117
|
+
//! This tutorial implements a `duck` storage service that sends API
|
|
118
|
+
//! requests to a super-powered duck. Gagaga!
|
|
119
|
+
//!
|
|
120
|
+
//! ## Scheme
|
|
121
|
+
//!
|
|
122
|
+
//! First of all, let's pick a good [`Scheme`] for our duck service. The
|
|
123
|
+
//! scheme should be unique and easy to understand. Normally we should
|
|
124
|
+
//! use its formal name.
|
|
125
|
+
//!
|
|
126
|
+
//! For example, we will use `s3` for AWS S3 Compatible Storage Service
|
|
127
|
+
//! instead of `aws` or `awss3`. This is because there are many storage
|
|
128
|
+
//! vendors that provide s3-like RESTful APIs, and our s3 service is
|
|
129
|
+
//! implemented to support all of them, not just AWS S3.
|
|
130
|
+
//!
|
|
131
|
+
//! Obviously, we can use `duck` as scheme, let's add a new variant in [`Scheme`], and implement all required functions like `Scheme::from_str` and `Scheme::into_static`:
|
|
132
|
+
//!
|
|
133
|
+
//! ```ignore
|
|
134
|
+
//! pub enum Scheme {
|
|
135
|
+
//! Duck,
|
|
136
|
+
//! }
|
|
137
|
+
//! ```
|
|
138
|
+
//!
|
|
139
|
+
//! ## Builder
|
|
140
|
+
//!
|
|
141
|
+
//! Then we can implement a builder for the duck service. The [`Builder`]
|
|
142
|
+
//! will provide APIs for users to configure, and they will create an
|
|
143
|
+
//! instance of a particular service.
|
|
144
|
+
//!
|
|
145
|
+
//! Let's create a `backend` mod under `services/duck` directory, and adding the following code.
|
|
146
|
+
//!
|
|
147
|
+
//! ```ignore
|
|
148
|
+
//! use crate::raw::*;
|
|
149
|
+
//! use crate::*;
|
|
150
|
+
//!
|
|
151
|
+
//! /// Duck Storage Service support. Gagaga!
|
|
152
|
+
//! ///
|
|
153
|
+
//! /// # Capabilities
|
|
154
|
+
//! ///
|
|
155
|
+
//! /// This service can be used to:
|
|
156
|
+
//! ///
|
|
157
|
+
//! /// - [x] read
|
|
158
|
+
//! /// - [ ] write
|
|
159
|
+
//! /// - [ ] list
|
|
160
|
+
//! /// - [ ] presign
|
|
161
|
+
//! ///
|
|
162
|
+
//! /// # Configuration
|
|
163
|
+
//! ///
|
|
164
|
+
//! /// - `root`: Set the work dir for backend.
|
|
165
|
+
//! ///
|
|
166
|
+
//! /// ## Via Builder
|
|
167
|
+
//! ///
|
|
168
|
+
//! /// ```no_run
|
|
169
|
+
//! /// use std::sync::Arc;
|
|
170
|
+
//! ///
|
|
171
|
+
//! /// use anyhow::Result;
|
|
172
|
+
//! /// use opendal::services::Duck;
|
|
173
|
+
//! /// use opendal::Operator;
|
|
174
|
+
//! ///
|
|
175
|
+
//! /// #[tokio::main]
|
|
176
|
+
//! /// async fn main() -> Result<()> {
|
|
177
|
+
//! /// // Create Duck backend builder.
|
|
178
|
+
//! /// let mut builder = DuckBuilder::default();
|
|
179
|
+
//! /// // Set the root for duck, all operations will happen under this root.
|
|
180
|
+
//! /// //
|
|
181
|
+
//! /// // NOTE: the root must be absolute path.
|
|
182
|
+
//! /// builder.root("/path/to/dir");
|
|
183
|
+
//! ///
|
|
184
|
+
//! /// let op: Operator = Operator::new(builder)?.finish();
|
|
185
|
+
//! ///
|
|
186
|
+
//! /// Ok(())
|
|
187
|
+
//! /// }
|
|
188
|
+
//! /// ```
|
|
189
|
+
//! #[derive(Default, Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
|
|
190
|
+
//! #[serde(default)]
|
|
191
|
+
//! #[non_exhaustive]
|
|
192
|
+
//! pub struct DuckConfig {
|
|
193
|
+
//! pub root: Option<String>,
|
|
194
|
+
//! }
|
|
195
|
+
//!
|
|
196
|
+
//! #[derive(Default, Clone)]
|
|
197
|
+
//! pub struct DuckBuilder {
|
|
198
|
+
//! config: DuckConfig,
|
|
199
|
+
//! }
|
|
200
|
+
//! ```
|
|
201
|
+
//!
|
|
202
|
+
//! Now let's implement the required APIs for `DuckConfig`:
|
|
203
|
+
//!
|
|
204
|
+
//! ```ignore
|
|
205
|
+
//! impl Configurator for DuckConfig {
|
|
206
|
+
//! type Builder = DuckBuilder;
|
|
207
|
+
//!
|
|
208
|
+
//! fn into_builder(self) -> Self::Builder {
|
|
209
|
+
//! DuckBuilder { config: self }
|
|
210
|
+
//! }
|
|
211
|
+
//! }
|
|
212
|
+
//! ```
|
|
213
|
+
//!
|
|
214
|
+
//! Note that `DuckBuilder` is part of our public API, so it needs to be
|
|
215
|
+
//! documented. And any changes you make will directly affect users, so
|
|
216
|
+
//! please take it seriously. Otherwise, you will be hunted down by many
|
|
217
|
+
//! angry ducks.
|
|
218
|
+
//!
|
|
219
|
+
//! Then, we can implement required APIs for `DuckBuilder`:
|
|
220
|
+
//!
|
|
221
|
+
//! ```ignore
|
|
222
|
+
//! impl DuckBuilder {
|
|
223
|
+
//! /// Set root of this backend.
|
|
224
|
+
//! ///
|
|
225
|
+
//! /// All operations will happen under this root.
|
|
226
|
+
//! pub fn root(&mut self, root: &str) -> &mut Self {
|
|
227
|
+
//! self.config.root = if root.is_empty() {
|
|
228
|
+
//! None
|
|
229
|
+
//! } else {
|
|
230
|
+
//! Some(root.to_string())
|
|
231
|
+
//! };
|
|
232
|
+
//!
|
|
233
|
+
//! self
|
|
234
|
+
//! }
|
|
235
|
+
//! }
|
|
236
|
+
//!
|
|
237
|
+
//! impl Builder for DuckBuilder {
|
|
238
|
+
//! type Config = DuckConfig;
|
|
239
|
+
//!
|
|
240
|
+
//! fn build(self) -> Result<impl Access> {
|
|
241
|
+
//! debug!("backend build started: {:?}", &self);
|
|
242
|
+
//!
|
|
243
|
+
//! let root = normalize_root(&self.config.root.clone().unwrap_or_default());
|
|
244
|
+
//! debug!("backend use root {}", &root);
|
|
245
|
+
//!
|
|
246
|
+
//! Ok(DuckBackend { root })
|
|
247
|
+
//! }
|
|
248
|
+
//! }
|
|
249
|
+
//! ```
|
|
250
|
+
//!
|
|
251
|
+
//! `DuckBuilder` is ready now, let's try to play with real ducks!
|
|
252
|
+
//!
|
|
253
|
+
//! ## Backend
|
|
254
|
+
//!
|
|
255
|
+
//! I'm sure you can see it already: `DuckBuilder` will build a
|
|
256
|
+
//! `DuckBackend` that implements [`Access`]. The backend is what we used
|
|
257
|
+
//! to communicate with the super-powered ducks!
|
|
258
|
+
//!
|
|
259
|
+
//! Let's keep adding more code under `backend.rs`:
|
|
260
|
+
//!
|
|
261
|
+
//! ```ignore
|
|
262
|
+
//! /// Duck storage service backend
|
|
263
|
+
//! #[derive(Clone, Debug)]
|
|
264
|
+
//! pub struct DuckBackend {
|
|
265
|
+
//! root: String,
|
|
266
|
+
//! }
|
|
267
|
+
//!
|
|
268
|
+
//! impl Access for DuckBackend {
|
|
269
|
+
//! type Reader = DuckReader;
|
|
270
|
+
//! type Writer = ();
|
|
271
|
+
//! type Lister = ();
|
|
272
|
+
//! type Deleter = ();
|
|
273
|
+
//!
|
|
274
|
+
//! fn info(&self) -> Arc<AccessorInfo> {
|
|
275
|
+
//! let am = AccessorInfo::default();
|
|
276
|
+
//! am.set_scheme("duck")
|
|
277
|
+
//! .set_root(&self.root)
|
|
278
|
+
//! .set_native_capability(
|
|
279
|
+
//! Capability {
|
|
280
|
+
//! read: true,
|
|
281
|
+
//! ..Default::default()
|
|
282
|
+
//! });
|
|
283
|
+
//!
|
|
284
|
+
//! am.into()
|
|
285
|
+
//! }
|
|
286
|
+
//!
|
|
287
|
+
//! async fn read(&self, path: &str, args: OpRead) -> Result<(RpRead, Self::Reader)> {
|
|
288
|
+
//! gagaga!()
|
|
289
|
+
//! }
|
|
290
|
+
//! }
|
|
291
|
+
//! ```
|
|
292
|
+
//!
|
|
293
|
+
//! Congratulations, we have implemented an [`Access`] that can talk to
|
|
294
|
+
//! Super Power Ducks!
|
|
295
|
+
//!
|
|
296
|
+
//! What!? There are no Super Power Ducks? So sad, but never mind, we have
|
|
297
|
+
//! really powerful storage services [here](https://github.com/apache/opendal/issues/5). Welcome to pick one to implement. I promise you won't
|
|
298
|
+
//! have to `gagaga!()` this time.
|
|
299
|
+
//!
|
|
300
|
+
//! [`Access`]: crate::raw::Access
|
|
301
|
+
//! [`Operation`]: crate::raw::Operation
|
|
302
|
+
//! [`Capability`]: crate::Capability
|
|
303
|
+
//! [`AccessorInfo`]: crate::raw::AccessorInfo
|
|
304
|
+
//! [`Scheme`]: crate::Scheme
|
|
305
|
+
//! [`Builder`]: crate::Builder
|
|
306
|
+
//! [`Configurator`]: crate::Configurator
|
|
@@ -0,0 +1,42 @@
|
|
|
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
|
+
//! The internal implementation details of [`Layer`].
|
|
19
|
+
//!
|
|
20
|
+
//! [`Layer`] itself is quite simple:
|
|
21
|
+
//!
|
|
22
|
+
//! ```ignore
|
|
23
|
+
//! pub trait Layer<A: Access> {
|
|
24
|
+
//! type LayeredAccess: Access;
|
|
25
|
+
//!
|
|
26
|
+
//! fn layer(&self, inner: A) -> Self::LayeredAccess;
|
|
27
|
+
//! }
|
|
28
|
+
//! ```
|
|
29
|
+
//!
|
|
30
|
+
//! `XxxLayer` will wrap input [`Access`] as inner and return a new [`Access`]. So normally the implementation of [`Layer`] will be split into two parts:
|
|
31
|
+
//!
|
|
32
|
+
//! - `XxxLayer` will implement [`Layer`] and return `XxxAccessor` as `Self::LayeredAccess`.
|
|
33
|
+
//! - `XxxAccess` will implement [`Access`] and be built by `XxxLayer`.
|
|
34
|
+
//!
|
|
35
|
+
//! Most layer only implements part of [`Access`], so we provide
|
|
36
|
+
//! [`LayeredAccess`] which will forward all unimplemented methods to
|
|
37
|
+
//! `inner`. It's highly recommend to implement [`LayeredAccess`] trait
|
|
38
|
+
//! instead.
|
|
39
|
+
//!
|
|
40
|
+
//! [`Layer`]: crate::raw::Layer
|
|
41
|
+
//! [`Access`]: crate::raw::Access
|
|
42
|
+
//! [`LayeredAccess`]: crate::raw::LayeredAccess
|