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.
Files changed (809) hide show
  1. checksums.yaml +7 -0
  2. data/.standard.yml +20 -0
  3. data/.tool-versions +1 -0
  4. data/.yardopts +1 -0
  5. data/Cargo.toml +65 -0
  6. data/DEPENDENCIES.md +9 -0
  7. data/DEPENDENCIES.rust.tsv +277 -0
  8. data/Gemfile +35 -0
  9. data/README.md +159 -0
  10. data/Rakefile +149 -0
  11. data/build.rs +22 -0
  12. data/core/CHANGELOG.md +4929 -0
  13. data/core/CONTRIBUTING.md +61 -0
  14. data/core/Cargo.lock +10259 -0
  15. data/core/Cargo.toml +437 -0
  16. data/core/DEPENDENCIES.md +3 -0
  17. data/core/DEPENDENCIES.rust.tsv +185 -0
  18. data/core/LICENSE +201 -0
  19. data/core/README.md +228 -0
  20. data/core/benches/README.md +18 -0
  21. data/core/benches/ops/README.md +26 -0
  22. data/core/benches/ops/main.rs +25 -0
  23. data/core/benches/ops/read.rs +100 -0
  24. data/core/benches/ops/utils.rs +59 -0
  25. data/core/benches/ops/write.rs +106 -0
  26. data/core/benches/types/README.md +9 -0
  27. data/core/benches/types/buffer.rs +114 -0
  28. data/core/benches/types/main.rs +23 -0
  29. data/core/benches/types/tasks.rs +64 -0
  30. data/core/benches/vs_fs/Cargo.toml +32 -0
  31. data/core/benches/vs_fs/README.md +35 -0
  32. data/core/benches/vs_fs/src/main.rs +83 -0
  33. data/core/benches/vs_s3/Cargo.toml +38 -0
  34. data/core/benches/vs_s3/README.md +55 -0
  35. data/core/benches/vs_s3/src/main.rs +123 -0
  36. data/core/edge/README.md +3 -0
  37. data/core/edge/file_write_on_full_disk/Cargo.toml +31 -0
  38. data/core/edge/file_write_on_full_disk/README.md +14 -0
  39. data/core/edge/file_write_on_full_disk/src/main.rs +43 -0
  40. data/core/edge/s3_aws_assume_role_with_web_identity/Cargo.toml +30 -0
  41. data/core/edge/s3_aws_assume_role_with_web_identity/README.md +18 -0
  42. data/core/edge/s3_aws_assume_role_with_web_identity/src/main.rs +34 -0
  43. data/core/edge/s3_read_on_wasm/.gitignore +3 -0
  44. data/core/edge/s3_read_on_wasm/Cargo.toml +38 -0
  45. data/core/edge/s3_read_on_wasm/README.md +42 -0
  46. data/core/edge/s3_read_on_wasm/src/lib.rs +60 -0
  47. data/core/edge/s3_read_on_wasm/webdriver.json +15 -0
  48. data/core/examples/README.md +23 -0
  49. data/core/examples/basic/Cargo.toml +29 -0
  50. data/core/examples/basic/README.md +15 -0
  51. data/core/examples/basic/src/main.rs +51 -0
  52. data/core/examples/concurrent-upload/Cargo.toml +29 -0
  53. data/core/examples/concurrent-upload/README.md +15 -0
  54. data/core/examples/concurrent-upload/src/main.rs +68 -0
  55. data/core/examples/multipart-upload/Cargo.toml +29 -0
  56. data/core/examples/multipart-upload/README.md +15 -0
  57. data/core/examples/multipart-upload/src/main.rs +56 -0
  58. data/core/fuzz/.gitignore +5 -0
  59. data/core/fuzz/Cargo.toml +92 -0
  60. data/core/fuzz/README.md +68 -0
  61. data/core/fuzz/fuzz_reader.rs +102 -0
  62. data/core/fuzz/fuzz_writer.rs +123 -0
  63. data/core/src/blocking/delete.rs +74 -0
  64. data/core/src/blocking/list.rs +71 -0
  65. data/core/src/blocking/mod.rs +33 -0
  66. data/core/src/blocking/operator.rs +729 -0
  67. data/core/src/blocking/read/buffer_iterator.rs +66 -0
  68. data/core/src/blocking/read/mod.rs +27 -0
  69. data/core/src/blocking/read/reader.rs +124 -0
  70. data/core/src/blocking/read/std_bytes_iterator.rs +69 -0
  71. data/core/src/blocking/read/std_reader.rs +95 -0
  72. data/core/src/blocking/write/mod.rs +22 -0
  73. data/core/src/blocking/write/std_writer.rs +82 -0
  74. data/core/src/blocking/write/writer.rs +109 -0
  75. data/core/src/docs/comparisons/mod.rs +30 -0
  76. data/core/src/docs/comparisons/vs_object_store.md +183 -0
  77. data/core/src/docs/concepts.rs +135 -0
  78. data/core/src/docs/internals/accessor.rs +306 -0
  79. data/core/src/docs/internals/layer.rs +42 -0
  80. data/core/src/docs/internals/mod.rs +62 -0
  81. data/core/src/docs/mod.rs +43 -0
  82. data/core/src/docs/performance/concurrent_write.md +101 -0
  83. data/core/src/docs/performance/http_optimization.md +124 -0
  84. data/core/src/docs/performance/mod.rs +32 -0
  85. data/core/src/docs/rfcs/0000_example.md +74 -0
  86. data/core/src/docs/rfcs/0000_foyer_integration.md +111 -0
  87. data/core/src/docs/rfcs/0041_object_native_api.md +185 -0
  88. data/core/src/docs/rfcs/0044_error_handle.md +198 -0
  89. data/core/src/docs/rfcs/0057_auto_region.md +160 -0
  90. data/core/src/docs/rfcs/0069_object_stream.md +145 -0
  91. data/core/src/docs/rfcs/0090_limited_reader.md +155 -0
  92. data/core/src/docs/rfcs/0112_path_normalization.md +79 -0
  93. data/core/src/docs/rfcs/0191_async_streaming_io.md +328 -0
  94. data/core/src/docs/rfcs/0203_remove_credential.md +96 -0
  95. data/core/src/docs/rfcs/0221_create_dir.md +89 -0
  96. data/core/src/docs/rfcs/0247_retryable_error.md +87 -0
  97. data/core/src/docs/rfcs/0293_object_id.md +67 -0
  98. data/core/src/docs/rfcs/0337_dir_entry.md +191 -0
  99. data/core/src/docs/rfcs/0409_accessor_capabilities.md +67 -0
  100. data/core/src/docs/rfcs/0413_presign.md +154 -0
  101. data/core/src/docs/rfcs/0423_command_line_interface.md +268 -0
  102. data/core/src/docs/rfcs/0429_init_from_iter.md +107 -0
  103. data/core/src/docs/rfcs/0438_multipart.md +163 -0
  104. data/core/src/docs/rfcs/0443_gateway.md +73 -0
  105. data/core/src/docs/rfcs/0501_new_builder.md +111 -0
  106. data/core/src/docs/rfcs/0554_write_refactor.md +96 -0
  107. data/core/src/docs/rfcs/0561_list_metadata_reuse.md +210 -0
  108. data/core/src/docs/rfcs/0599_blocking_api.md +157 -0
  109. data/core/src/docs/rfcs/0623_redis_service.md +300 -0
  110. data/core/src/docs/rfcs/0627_split_capabilities.md +89 -0
  111. data/core/src/docs/rfcs/0661_path_in_accessor.md +126 -0
  112. data/core/src/docs/rfcs/0793_generic_kv_services.md +209 -0
  113. data/core/src/docs/rfcs/0926_object_reader.md +93 -0
  114. data/core/src/docs/rfcs/0977_refactor_error.md +151 -0
  115. data/core/src/docs/rfcs/1085_object_handler.md +73 -0
  116. data/core/src/docs/rfcs/1391_object_metadataer.md +110 -0
  117. data/core/src/docs/rfcs/1398_query_based_metadata.md +125 -0
  118. data/core/src/docs/rfcs/1420_object_writer.md +147 -0
  119. data/core/src/docs/rfcs/1477_remove_object_concept.md +159 -0
  120. data/core/src/docs/rfcs/1735_operation_extension.md +117 -0
  121. data/core/src/docs/rfcs/2083_writer_sink_api.md +106 -0
  122. data/core/src/docs/rfcs/2133_append_api.md +88 -0
  123. data/core/src/docs/rfcs/2299_chain_based_operator_api.md +99 -0
  124. data/core/src/docs/rfcs/2602_object_versioning.md +138 -0
  125. data/core/src/docs/rfcs/2758_merge_append_into_write.md +79 -0
  126. data/core/src/docs/rfcs/2774_lister_api.md +66 -0
  127. data/core/src/docs/rfcs/2779_list_with_metakey.md +143 -0
  128. data/core/src/docs/rfcs/2852_native_capability.md +58 -0
  129. data/core/src/docs/rfcs/2884_merge_range_read_into_read.md +80 -0
  130. data/core/src/docs/rfcs/3017_remove_write_copy_from.md +94 -0
  131. data/core/src/docs/rfcs/3197_config.md +237 -0
  132. data/core/src/docs/rfcs/3232_align_list_api.md +69 -0
  133. data/core/src/docs/rfcs/3243_list_prefix.md +128 -0
  134. data/core/src/docs/rfcs/3356_lazy_reader.md +111 -0
  135. data/core/src/docs/rfcs/3526_list_recursive.md +59 -0
  136. data/core/src/docs/rfcs/3574_concurrent_stat_in_list.md +80 -0
  137. data/core/src/docs/rfcs/3734_buffered_reader.md +64 -0
  138. data/core/src/docs/rfcs/3898_concurrent_writer.md +66 -0
  139. data/core/src/docs/rfcs/3911_deleter_api.md +165 -0
  140. data/core/src/docs/rfcs/4382_range_based_read.md +213 -0
  141. data/core/src/docs/rfcs/4638_executor.md +215 -0
  142. data/core/src/docs/rfcs/5314_remove_metakey.md +120 -0
  143. data/core/src/docs/rfcs/5444_operator_from_uri.md +162 -0
  144. data/core/src/docs/rfcs/5479_context.md +140 -0
  145. data/core/src/docs/rfcs/5485_conditional_reader.md +112 -0
  146. data/core/src/docs/rfcs/5495_list_with_deleted.md +81 -0
  147. data/core/src/docs/rfcs/5556_write_returns_metadata.md +121 -0
  148. data/core/src/docs/rfcs/5871_read_returns_metadata.md +112 -0
  149. data/core/src/docs/rfcs/6189_remove_native_blocking.md +106 -0
  150. data/core/src/docs/rfcs/6209_glob_support.md +132 -0
  151. data/core/src/docs/rfcs/6213_options_api.md +142 -0
  152. data/core/src/docs/rfcs/README.md +62 -0
  153. data/core/src/docs/rfcs/mod.rs +278 -0
  154. data/core/src/docs/upgrade.md +1556 -0
  155. data/core/src/layers/async_backtrace.rs +174 -0
  156. data/core/src/layers/await_tree.rs +202 -0
  157. data/core/src/layers/capability_check.rs +239 -0
  158. data/core/src/layers/chaos.rs +170 -0
  159. data/core/src/layers/complete.rs +385 -0
  160. data/core/src/layers/concurrent_limit.rs +322 -0
  161. data/core/src/layers/correctness_check.rs +440 -0
  162. data/core/src/layers/dtrace.rs +294 -0
  163. data/core/src/layers/error_context.rs +310 -0
  164. data/core/src/layers/fastmetrics.rs +525 -0
  165. data/core/src/layers/fastrace.rs +271 -0
  166. data/core/src/layers/http_client.rs +206 -0
  167. data/core/src/layers/immutable_index.rs +408 -0
  168. data/core/src/layers/logging.rs +842 -0
  169. data/core/src/layers/metrics.rs +182 -0
  170. data/core/src/layers/mime_guess.rs +199 -0
  171. data/core/src/layers/mod.rs +130 -0
  172. data/core/src/layers/observe/metrics.rs +936 -0
  173. data/core/src/layers/observe/mod.rs +93 -0
  174. data/core/src/layers/otelmetrics.rs +496 -0
  175. data/core/src/layers/oteltrace.rs +203 -0
  176. data/core/src/layers/prometheus.rs +686 -0
  177. data/core/src/layers/prometheus_client.rs +519 -0
  178. data/core/src/layers/retry.rs +933 -0
  179. data/core/src/layers/throttle.rs +204 -0
  180. data/core/src/layers/timeout.rs +513 -0
  181. data/core/src/layers/tracing.rs +349 -0
  182. data/core/src/layers/type_eraser.rs +91 -0
  183. data/core/src/lib.rs +204 -0
  184. data/core/src/raw/accessor.rs +856 -0
  185. data/core/src/raw/adapters/kv/api.rs +164 -0
  186. data/core/src/raw/adapters/kv/backend.rs +253 -0
  187. data/core/src/raw/adapters/kv/mod.rs +31 -0
  188. data/core/src/raw/adapters/mod.rs +50 -0
  189. data/core/src/raw/adapters/typed_kv/api.rs +171 -0
  190. data/core/src/raw/adapters/typed_kv/backend.rs +279 -0
  191. data/core/src/raw/adapters/typed_kv/mod.rs +29 -0
  192. data/core/src/raw/atomic_util.rs +57 -0
  193. data/core/src/raw/azure.rs +570 -0
  194. data/core/src/raw/chrono_util.rs +109 -0
  195. data/core/src/raw/enum_utils.rs +201 -0
  196. data/core/src/raw/futures_util.rs +470 -0
  197. data/core/src/raw/http_util/body.rs +144 -0
  198. data/core/src/raw/http_util/bytes_content_range.rs +239 -0
  199. data/core/src/raw/http_util/bytes_range.rs +260 -0
  200. data/core/src/raw/http_util/client.rs +276 -0
  201. data/core/src/raw/http_util/error.rs +68 -0
  202. data/core/src/raw/http_util/header.rs +356 -0
  203. data/core/src/raw/http_util/mod.rs +78 -0
  204. data/core/src/raw/http_util/multipart.rs +1180 -0
  205. data/core/src/raw/http_util/uri.rs +190 -0
  206. data/core/src/raw/layer.rs +295 -0
  207. data/core/src/raw/mod.rs +101 -0
  208. data/core/src/raw/oio/buf/flex_buf.rs +118 -0
  209. data/core/src/raw/oio/buf/mod.rs +25 -0
  210. data/core/src/raw/oio/buf/pooled_buf.rs +126 -0
  211. data/core/src/raw/oio/buf/queue_buf.rs +117 -0
  212. data/core/src/raw/oio/delete/api.rs +102 -0
  213. data/core/src/raw/oio/delete/batch_delete.rs +127 -0
  214. data/core/src/raw/oio/delete/mod.rs +30 -0
  215. data/core/src/raw/oio/delete/one_shot_delete.rs +79 -0
  216. data/core/src/raw/oio/entry.rs +89 -0
  217. data/core/src/raw/oio/list/api.rs +69 -0
  218. data/core/src/raw/oio/list/flat_list.rs +137 -0
  219. data/core/src/raw/oio/list/hierarchy_list.rs +135 -0
  220. data/core/src/raw/oio/list/mod.rs +35 -0
  221. data/core/src/raw/oio/list/page_list.rs +105 -0
  222. data/core/src/raw/oio/list/prefix_list.rs +64 -0
  223. data/core/src/raw/oio/mod.rs +40 -0
  224. data/core/src/raw/oio/read/api.rs +119 -0
  225. data/core/src/raw/oio/read/mod.rs +21 -0
  226. data/core/src/raw/oio/write/api.rs +103 -0
  227. data/core/src/raw/oio/write/append_write.rs +111 -0
  228. data/core/src/raw/oio/write/block_write.rs +405 -0
  229. data/core/src/raw/oio/write/mod.rs +42 -0
  230. data/core/src/raw/oio/write/multipart_write.rs +518 -0
  231. data/core/src/raw/oio/write/one_shot_write.rs +77 -0
  232. data/core/src/raw/oio/write/position_write.rs +284 -0
  233. data/core/src/raw/operation.rs +88 -0
  234. data/core/src/raw/ops.rs +917 -0
  235. data/core/src/raw/path.rs +451 -0
  236. data/core/src/raw/path_cache.rs +244 -0
  237. data/core/src/raw/rps.rs +249 -0
  238. data/core/src/raw/serde_util.rs +423 -0
  239. data/core/src/raw/std_io_util.rs +65 -0
  240. data/core/src/raw/tests/mod.rs +30 -0
  241. data/core/src/raw/tests/read.rs +116 -0
  242. data/core/src/raw/tests/utils.rs +80 -0
  243. data/core/src/raw/tests/write.rs +79 -0
  244. data/core/src/raw/tokio_util.rs +24 -0
  245. data/core/src/raw/version.rs +19 -0
  246. data/core/src/services/aliyun_drive/backend.rs +421 -0
  247. data/core/src/services/aliyun_drive/config.rs +72 -0
  248. data/core/src/services/aliyun_drive/core.rs +651 -0
  249. data/core/src/services/aliyun_drive/delete.rs +51 -0
  250. data/core/src/services/aliyun_drive/docs.md +61 -0
  251. data/core/src/services/aliyun_drive/error.rs +56 -0
  252. data/core/src/services/aliyun_drive/lister.rs +134 -0
  253. data/core/src/services/aliyun_drive/mod.rs +39 -0
  254. data/core/src/services/aliyun_drive/writer.rs +114 -0
  255. data/core/src/services/alluxio/backend.rs +257 -0
  256. data/core/src/services/alluxio/config.rs +50 -0
  257. data/core/src/services/alluxio/core.rs +367 -0
  258. data/core/src/services/alluxio/delete.rs +38 -0
  259. data/core/src/services/alluxio/docs.md +45 -0
  260. data/core/src/services/alluxio/error.rs +99 -0
  261. data/core/src/services/alluxio/lister.rs +73 -0
  262. data/core/src/services/alluxio/mod.rs +39 -0
  263. data/core/src/services/alluxio/writer.rs +74 -0
  264. data/core/src/services/azblob/backend.rs +594 -0
  265. data/core/src/services/azblob/config.rs +220 -0
  266. data/core/src/services/azblob/core.rs +937 -0
  267. data/core/src/services/azblob/delete.rs +108 -0
  268. data/core/src/services/azblob/docs.md +77 -0
  269. data/core/src/services/azblob/error.rs +164 -0
  270. data/core/src/services/azblob/lister.rs +107 -0
  271. data/core/src/services/azblob/mod.rs +38 -0
  272. data/core/src/services/azblob/writer.rs +177 -0
  273. data/core/src/services/azdls/backend.rs +435 -0
  274. data/core/src/services/azdls/config.rs +89 -0
  275. data/core/src/services/azdls/core.rs +388 -0
  276. data/core/src/services/azdls/delete.rs +48 -0
  277. data/core/src/services/azdls/docs.md +73 -0
  278. data/core/src/services/azdls/error.rs +107 -0
  279. data/core/src/services/azdls/lister.rs +165 -0
  280. data/core/src/services/azdls/mod.rs +38 -0
  281. data/core/src/services/azdls/writer.rs +129 -0
  282. data/core/src/services/azfile/backend.rs +373 -0
  283. data/core/src/services/azfile/config.rs +61 -0
  284. data/core/src/services/azfile/core.rs +435 -0
  285. data/core/src/services/azfile/delete.rs +51 -0
  286. data/core/src/services/azfile/docs.md +65 -0
  287. data/core/src/services/azfile/error.rs +108 -0
  288. data/core/src/services/azfile/lister.rs +217 -0
  289. data/core/src/services/azfile/mod.rs +39 -0
  290. data/core/src/services/azfile/writer.rs +92 -0
  291. data/core/src/services/b2/backend.rs +434 -0
  292. data/core/src/services/b2/config.rs +64 -0
  293. data/core/src/services/b2/core.rs +742 -0
  294. data/core/src/services/b2/delete.rs +56 -0
  295. data/core/src/services/b2/docs.md +54 -0
  296. data/core/src/services/b2/error.rs +132 -0
  297. data/core/src/services/b2/lister.rs +110 -0
  298. data/core/src/services/b2/mod.rs +39 -0
  299. data/core/src/services/b2/writer.rs +189 -0
  300. data/core/src/services/cacache/backend.rs +160 -0
  301. data/core/src/services/cacache/config.rs +28 -0
  302. data/core/src/services/cacache/core.rs +96 -0
  303. data/core/src/services/cacache/delete.rs +39 -0
  304. data/core/src/services/cacache/docs.md +38 -0
  305. data/core/src/services/cacache/mod.rs +34 -0
  306. data/core/src/services/cacache/writer.rs +61 -0
  307. data/core/src/services/cloudflare_kv/backend.rs +513 -0
  308. data/core/src/services/cloudflare_kv/config.rs +55 -0
  309. data/core/src/services/cloudflare_kv/core.rs +168 -0
  310. data/core/src/services/cloudflare_kv/delete.rs +119 -0
  311. data/core/src/services/cloudflare_kv/docs.md +21 -0
  312. data/core/src/services/cloudflare_kv/error.rs +79 -0
  313. data/core/src/services/cloudflare_kv/lister.rs +170 -0
  314. data/core/src/services/cloudflare_kv/mod.rs +39 -0
  315. data/core/src/services/cloudflare_kv/model.rs +76 -0
  316. data/core/src/services/cloudflare_kv/writer.rs +68 -0
  317. data/core/src/services/compfs/backend.rs +290 -0
  318. data/core/src/services/compfs/config.rs +30 -0
  319. data/core/src/services/compfs/core.rs +159 -0
  320. data/core/src/services/compfs/delete.rs +53 -0
  321. data/core/src/services/compfs/lister.rs +98 -0
  322. data/core/src/services/compfs/mod.rs +38 -0
  323. data/core/src/services/compfs/reader.rs +79 -0
  324. data/core/src/services/compfs/writer.rs +90 -0
  325. data/core/src/services/cos/backend.rs +442 -0
  326. data/core/src/services/cos/config.rs +54 -0
  327. data/core/src/services/cos/core.rs +761 -0
  328. data/core/src/services/cos/delete.rs +48 -0
  329. data/core/src/services/cos/docs.md +55 -0
  330. data/core/src/services/cos/error.rs +105 -0
  331. data/core/src/services/cos/lister.rs +237 -0
  332. data/core/src/services/cos/mod.rs +39 -0
  333. data/core/src/services/cos/writer.rs +234 -0
  334. data/core/src/services/d1/backend.rs +330 -0
  335. data/core/src/services/d1/config.rs +55 -0
  336. data/core/src/services/d1/docs.md +48 -0
  337. data/core/src/services/d1/error.rs +79 -0
  338. data/core/src/services/d1/mod.rs +29 -0
  339. data/core/src/services/d1/model.rs +125 -0
  340. data/core/src/services/dashmap/backend.rs +203 -0
  341. data/core/src/services/dashmap/config.rs +37 -0
  342. data/core/src/services/dashmap/core.rs +61 -0
  343. data/core/src/services/dashmap/delete.rs +40 -0
  344. data/core/src/services/dashmap/docs.md +38 -0
  345. data/core/src/services/dashmap/lister.rs +63 -0
  346. data/core/src/services/dashmap/mod.rs +36 -0
  347. data/core/src/services/dashmap/writer.rs +87 -0
  348. data/core/src/services/dbfs/backend.rs +258 -0
  349. data/core/src/services/dbfs/config.rs +48 -0
  350. data/core/src/services/dbfs/core.rs +191 -0
  351. data/core/src/services/dbfs/delete.rs +49 -0
  352. data/core/src/services/dbfs/docs.md +57 -0
  353. data/core/src/services/dbfs/error.rs +74 -0
  354. data/core/src/services/dbfs/lister.rs +96 -0
  355. data/core/src/services/dbfs/mod.rs +38 -0
  356. data/core/src/services/dbfs/writer.rs +64 -0
  357. data/core/src/services/dropbox/backend.rs +187 -0
  358. data/core/src/services/dropbox/builder.rs +222 -0
  359. data/core/src/services/dropbox/config.rs +47 -0
  360. data/core/src/services/dropbox/core.rs +496 -0
  361. data/core/src/services/dropbox/delete.rs +54 -0
  362. data/core/src/services/dropbox/docs.md +64 -0
  363. data/core/src/services/dropbox/error.rs +85 -0
  364. data/core/src/services/dropbox/lister.rs +117 -0
  365. data/core/src/services/dropbox/mod.rs +40 -0
  366. data/core/src/services/dropbox/writer.rs +51 -0
  367. data/core/src/services/etcd/backend.rs +345 -0
  368. data/core/src/services/etcd/config.rs +86 -0
  369. data/core/src/services/etcd/core.rs +143 -0
  370. data/core/src/services/etcd/deleter.rs +41 -0
  371. data/core/src/services/etcd/docs.md +45 -0
  372. data/core/src/services/etcd/error.rs +26 -0
  373. data/core/src/services/etcd/lister.rs +79 -0
  374. data/core/src/services/etcd/mod.rs +36 -0
  375. data/core/src/services/etcd/writer.rs +61 -0
  376. data/core/src/services/foundationdb/backend.rs +171 -0
  377. data/core/src/services/foundationdb/config.rs +45 -0
  378. data/core/src/services/foundationdb/docs.md +42 -0
  379. data/core/src/services/foundationdb/mod.rs +24 -0
  380. data/core/src/services/fs/backend.rs +299 -0
  381. data/core/src/services/fs/config.rs +33 -0
  382. data/core/src/services/fs/core.rs +227 -0
  383. data/core/src/services/fs/delete.rs +53 -0
  384. data/core/src/services/fs/docs.md +49 -0
  385. data/core/src/services/fs/error.rs +31 -0
  386. data/core/src/services/fs/lister.rs +81 -0
  387. data/core/src/services/fs/mod.rs +40 -0
  388. data/core/src/services/fs/reader.rs +83 -0
  389. data/core/src/services/fs/writer.rs +212 -0
  390. data/core/src/services/ftp/backend.rs +388 -0
  391. data/core/src/services/ftp/config.rs +46 -0
  392. data/core/src/services/ftp/core.rs +136 -0
  393. data/core/src/services/ftp/delete.rs +62 -0
  394. data/core/src/services/ftp/docs.md +42 -0
  395. data/core/src/services/ftp/err.rs +47 -0
  396. data/core/src/services/ftp/lister.rs +72 -0
  397. data/core/src/services/ftp/mod.rs +41 -0
  398. data/core/src/services/ftp/reader.rs +84 -0
  399. data/core/src/services/ftp/writer.rs +122 -0
  400. data/core/src/services/gcs/backend.rs +499 -0
  401. data/core/src/services/gcs/config.rs +168 -0
  402. data/core/src/services/gcs/core.rs +1079 -0
  403. data/core/src/services/gcs/delete.rs +98 -0
  404. data/core/src/services/gcs/docs.md +76 -0
  405. data/core/src/services/gcs/error.rs +122 -0
  406. data/core/src/services/gcs/lister.rs +136 -0
  407. data/core/src/services/gcs/mod.rs +40 -0
  408. data/core/src/services/gcs/uri.rs +75 -0
  409. data/core/src/services/gcs/writer.rs +163 -0
  410. data/core/src/services/gdrive/backend.rs +176 -0
  411. data/core/src/services/gdrive/builder.rs +228 -0
  412. data/core/src/services/gdrive/config.rs +47 -0
  413. data/core/src/services/gdrive/core.rs +499 -0
  414. data/core/src/services/gdrive/delete.rs +57 -0
  415. data/core/src/services/gdrive/docs.md +65 -0
  416. data/core/src/services/gdrive/error.rs +80 -0
  417. data/core/src/services/gdrive/lister.rs +110 -0
  418. data/core/src/services/gdrive/mod.rs +40 -0
  419. data/core/src/services/gdrive/writer.rs +77 -0
  420. data/core/src/services/ghac/backend.rs +285 -0
  421. data/core/src/services/ghac/config.rs +36 -0
  422. data/core/src/services/ghac/core.rs +459 -0
  423. data/core/src/services/ghac/docs.md +84 -0
  424. data/core/src/services/ghac/error.rs +52 -0
  425. data/core/src/services/ghac/mod.rs +35 -0
  426. data/core/src/services/ghac/writer.rs +201 -0
  427. data/core/src/services/github/backend.rs +285 -0
  428. data/core/src/services/github/config.rs +59 -0
  429. data/core/src/services/github/core.rs +351 -0
  430. data/core/src/services/github/delete.rs +41 -0
  431. data/core/src/services/github/docs.md +52 -0
  432. data/core/src/services/github/error.rs +101 -0
  433. data/core/src/services/github/lister.rs +112 -0
  434. data/core/src/services/github/mod.rs +38 -0
  435. data/core/src/services/github/writer.rs +51 -0
  436. data/core/src/services/gridfs/backend.rs +166 -0
  437. data/core/src/services/gridfs/config.rs +50 -0
  438. data/core/src/services/gridfs/core.rs +154 -0
  439. data/core/src/services/gridfs/docs.md +46 -0
  440. data/core/src/services/gridfs/mod.rs +26 -0
  441. data/core/src/services/hdfs/backend.rs +413 -0
  442. data/core/src/services/hdfs/config.rs +59 -0
  443. data/core/src/services/hdfs/delete.rs +62 -0
  444. data/core/src/services/hdfs/docs.md +140 -0
  445. data/core/src/services/hdfs/lister.rs +70 -0
  446. data/core/src/services/hdfs/mod.rs +36 -0
  447. data/core/src/services/hdfs/reader.rs +79 -0
  448. data/core/src/services/hdfs/writer.rs +104 -0
  449. data/core/src/services/hdfs_native/backend.rs +340 -0
  450. data/core/src/services/hdfs_native/config.rs +45 -0
  451. data/core/src/services/hdfs_native/delete.rs +47 -0
  452. data/core/src/services/hdfs_native/docs.md +35 -0
  453. data/core/src/services/hdfs_native/error.rs +59 -0
  454. data/core/src/services/hdfs_native/lister.rs +85 -0
  455. data/core/src/services/hdfs_native/mod.rs +39 -0
  456. data/core/src/services/hdfs_native/reader.rs +62 -0
  457. data/core/src/services/hdfs_native/writer.rs +61 -0
  458. data/core/src/services/http/backend.rs +291 -0
  459. data/core/src/services/http/config.rs +49 -0
  460. data/core/src/services/http/core.rs +125 -0
  461. data/core/src/services/http/docs.md +45 -0
  462. data/core/src/services/http/error.rs +53 -0
  463. data/core/src/services/http/mod.rs +32 -0
  464. data/core/src/services/huggingface/backend.rs +289 -0
  465. data/core/src/services/huggingface/config.rs +75 -0
  466. data/core/src/services/huggingface/core.rs +406 -0
  467. data/core/src/services/huggingface/docs.md +61 -0
  468. data/core/src/services/huggingface/error.rs +93 -0
  469. data/core/src/services/huggingface/lister.rs +91 -0
  470. data/core/src/services/huggingface/mod.rs +34 -0
  471. data/core/src/services/ipfs/backend.rs +257 -0
  472. data/core/src/services/ipfs/config.rs +32 -0
  473. data/core/src/services/ipfs/core.rs +239 -0
  474. data/core/src/services/ipfs/docs.md +45 -0
  475. data/core/src/services/ipfs/error.rs +52 -0
  476. data/core/src/services/ipfs/ipld.rs +162 -0
  477. data/core/src/services/ipfs/mod.rs +34 -0
  478. data/core/src/services/ipmfs/backend.rs +147 -0
  479. data/core/src/services/ipmfs/builder.rs +166 -0
  480. data/core/src/services/ipmfs/config.rs +32 -0
  481. data/core/src/services/ipmfs/core.rs +142 -0
  482. data/core/src/services/ipmfs/delete.rs +48 -0
  483. data/core/src/services/ipmfs/docs.md +14 -0
  484. data/core/src/services/ipmfs/error.rs +83 -0
  485. data/core/src/services/ipmfs/lister.rs +135 -0
  486. data/core/src/services/ipmfs/mod.rs +40 -0
  487. data/core/src/services/ipmfs/writer.rs +49 -0
  488. data/core/src/services/koofr/backend.rs +361 -0
  489. data/core/src/services/koofr/config.rs +50 -0
  490. data/core/src/services/koofr/core.rs +458 -0
  491. data/core/src/services/koofr/delete.rs +50 -0
  492. data/core/src/services/koofr/docs.md +51 -0
  493. data/core/src/services/koofr/error.rs +72 -0
  494. data/core/src/services/koofr/lister.rs +88 -0
  495. data/core/src/services/koofr/mod.rs +38 -0
  496. data/core/src/services/koofr/writer.rs +53 -0
  497. data/core/src/services/lakefs/backend.rs +309 -0
  498. data/core/src/services/lakefs/config.rs +81 -0
  499. data/core/src/services/lakefs/core.rs +261 -0
  500. data/core/src/services/lakefs/delete.rs +54 -0
  501. data/core/src/services/lakefs/docs.md +62 -0
  502. data/core/src/services/lakefs/error.rs +93 -0
  503. data/core/src/services/lakefs/lister.rs +120 -0
  504. data/core/src/services/lakefs/mod.rs +38 -0
  505. data/core/src/services/lakefs/writer.rs +50 -0
  506. data/core/src/services/memcached/backend.rs +284 -0
  507. data/core/src/services/memcached/binary.rs +289 -0
  508. data/core/src/services/memcached/config.rs +43 -0
  509. data/core/src/services/memcached/docs.md +47 -0
  510. data/core/src/services/memcached/mod.rs +27 -0
  511. data/core/src/services/memory/backend.rs +205 -0
  512. data/core/src/services/memory/config.rs +30 -0
  513. data/core/src/services/memory/core.rs +80 -0
  514. data/core/src/services/memory/delete.rs +42 -0
  515. data/core/src/services/memory/docs.md +36 -0
  516. data/core/src/services/memory/lister.rs +56 -0
  517. data/core/src/services/memory/mod.rs +36 -0
  518. data/core/src/services/memory/writer.rs +85 -0
  519. data/core/src/services/mini_moka/backend.rs +260 -0
  520. data/core/src/services/mini_moka/config.rs +56 -0
  521. data/core/src/services/mini_moka/core.rs +52 -0
  522. data/core/src/services/mini_moka/delete.rs +42 -0
  523. data/core/src/services/mini_moka/docs.md +19 -0
  524. data/core/src/services/mini_moka/lister.rs +68 -0
  525. data/core/src/services/mini_moka/mod.rs +36 -0
  526. data/core/src/services/mini_moka/writer.rs +84 -0
  527. data/core/src/services/mod.rs +206 -0
  528. data/core/src/services/moka/backend.rs +326 -0
  529. data/core/src/services/moka/config.rs +59 -0
  530. data/core/src/services/moka/core.rs +62 -0
  531. data/core/src/services/moka/delete.rs +42 -0
  532. data/core/src/services/moka/docs.md +42 -0
  533. data/core/src/services/moka/lister.rs +65 -0
  534. data/core/src/services/moka/mod.rs +41 -0
  535. data/core/src/services/moka/writer.rs +83 -0
  536. data/core/src/services/mongodb/backend.rs +291 -0
  537. data/core/src/services/mongodb/config.rs +54 -0
  538. data/core/src/services/mongodb/docs.md +49 -0
  539. data/core/src/services/mongodb/mod.rs +24 -0
  540. data/core/src/services/monoiofs/backend.rs +238 -0
  541. data/core/src/services/monoiofs/config.rs +34 -0
  542. data/core/src/services/monoiofs/core.rs +313 -0
  543. data/core/src/services/monoiofs/delete.rs +64 -0
  544. data/core/src/services/monoiofs/docs.md +46 -0
  545. data/core/src/services/monoiofs/mod.rs +36 -0
  546. data/core/src/services/monoiofs/reader.rs +147 -0
  547. data/core/src/services/monoiofs/writer.rs +189 -0
  548. data/core/src/services/mysql/backend.rs +256 -0
  549. data/core/src/services/mysql/config.rs +66 -0
  550. data/core/src/services/mysql/docs.md +47 -0
  551. data/core/src/services/mysql/mod.rs +24 -0
  552. data/core/src/services/obs/backend.rs +442 -0
  553. data/core/src/services/obs/config.rs +53 -0
  554. data/core/src/services/obs/core.rs +608 -0
  555. data/core/src/services/obs/delete.rs +48 -0
  556. data/core/src/services/obs/docs.md +54 -0
  557. data/core/src/services/obs/error.rs +106 -0
  558. data/core/src/services/obs/lister.rs +101 -0
  559. data/core/src/services/obs/mod.rs +38 -0
  560. data/core/src/services/obs/writer.rs +235 -0
  561. data/core/src/services/onedrive/backend.rs +127 -0
  562. data/core/src/services/onedrive/builder.rs +236 -0
  563. data/core/src/services/onedrive/config.rs +49 -0
  564. data/core/src/services/onedrive/core.rs +691 -0
  565. data/core/src/services/onedrive/delete.rs +47 -0
  566. data/core/src/services/onedrive/docs.md +115 -0
  567. data/core/src/services/onedrive/error.rs +61 -0
  568. data/core/src/services/onedrive/graph_model.rs +425 -0
  569. data/core/src/services/onedrive/lister.rs +150 -0
  570. data/core/src/services/onedrive/mod.rs +42 -0
  571. data/core/src/services/onedrive/writer.rs +168 -0
  572. data/core/src/services/opfs/backend.rs +50 -0
  573. data/core/src/services/opfs/config.rs +25 -0
  574. data/core/src/services/opfs/core.rs +74 -0
  575. data/core/src/services/opfs/docs.md +18 -0
  576. data/core/src/services/opfs/error.rs +27 -0
  577. data/core/src/services/opfs/mod.rs +30 -0
  578. data/core/src/services/opfs/utils.rs +70 -0
  579. data/core/src/services/oss/backend.rs +734 -0
  580. data/core/src/services/oss/config.rs +113 -0
  581. data/core/src/services/oss/core.rs +1088 -0
  582. data/core/src/services/oss/delete.rs +109 -0
  583. data/core/src/services/oss/docs.md +74 -0
  584. data/core/src/services/oss/error.rs +109 -0
  585. data/core/src/services/oss/lister.rs +256 -0
  586. data/core/src/services/oss/mod.rs +38 -0
  587. data/core/src/services/oss/writer.rs +228 -0
  588. data/core/src/services/pcloud/backend.rs +358 -0
  589. data/core/src/services/pcloud/config.rs +51 -0
  590. data/core/src/services/pcloud/core.rs +461 -0
  591. data/core/src/services/pcloud/delete.rs +66 -0
  592. data/core/src/services/pcloud/docs.md +51 -0
  593. data/core/src/services/pcloud/error.rs +88 -0
  594. data/core/src/services/pcloud/lister.rs +95 -0
  595. data/core/src/services/pcloud/mod.rs +38 -0
  596. data/core/src/services/pcloud/writer.rs +66 -0
  597. data/core/src/services/persy/backend.rs +226 -0
  598. data/core/src/services/persy/config.rs +32 -0
  599. data/core/src/services/persy/docs.md +43 -0
  600. data/core/src/services/persy/mod.rs +24 -0
  601. data/core/src/services/postgresql/backend.rs +258 -0
  602. data/core/src/services/postgresql/config.rs +66 -0
  603. data/core/src/services/postgresql/docs.md +47 -0
  604. data/core/src/services/postgresql/mod.rs +24 -0
  605. data/core/src/services/redb/backend.rs +280 -0
  606. data/core/src/services/redb/config.rs +34 -0
  607. data/core/src/services/redb/docs.md +41 -0
  608. data/core/src/services/redb/mod.rs +24 -0
  609. data/core/src/services/redis/backend.rs +442 -0
  610. data/core/src/services/redis/config.rs +79 -0
  611. data/core/src/services/redis/core.rs +209 -0
  612. data/core/src/services/redis/delete.rs +40 -0
  613. data/core/src/services/redis/docs.md +43 -0
  614. data/core/src/services/redis/mod.rs +34 -0
  615. data/core/src/services/redis/writer.rs +57 -0
  616. data/core/src/services/rocksdb/backend.rs +159 -0
  617. data/core/src/services/rocksdb/config.rs +34 -0
  618. data/core/src/services/rocksdb/docs.md +54 -0
  619. data/core/src/services/rocksdb/mod.rs +24 -0
  620. data/core/src/services/s3/backend.rs +1293 -0
  621. data/core/src/services/s3/compatible_services.md +126 -0
  622. data/core/src/services/s3/config.rs +327 -0
  623. data/core/src/services/s3/core.rs +1741 -0
  624. data/core/src/services/s3/delete.rs +109 -0
  625. data/core/src/services/s3/docs.md +244 -0
  626. data/core/src/services/s3/error.rs +171 -0
  627. data/core/src/services/s3/lister.rs +405 -0
  628. data/core/src/services/s3/mod.rs +38 -0
  629. data/core/src/services/s3/writer.rs +262 -0
  630. data/core/src/services/seafile/backend.rs +297 -0
  631. data/core/src/services/seafile/config.rs +56 -0
  632. data/core/src/services/seafile/core.rs +475 -0
  633. data/core/src/services/seafile/delete.rs +40 -0
  634. data/core/src/services/seafile/docs.md +54 -0
  635. data/core/src/services/seafile/error.rs +86 -0
  636. data/core/src/services/seafile/lister.rs +83 -0
  637. data/core/src/services/seafile/mod.rs +38 -0
  638. data/core/src/services/seafile/writer.rs +55 -0
  639. data/core/src/services/sftp/backend.rs +397 -0
  640. data/core/src/services/sftp/config.rs +50 -0
  641. data/core/src/services/sftp/core.rs +154 -0
  642. data/core/src/services/sftp/delete.rs +55 -0
  643. data/core/src/services/sftp/docs.md +49 -0
  644. data/core/src/services/sftp/error.rs +57 -0
  645. data/core/src/services/sftp/lister.rs +88 -0
  646. data/core/src/services/sftp/mod.rs +42 -0
  647. data/core/src/services/sftp/reader.rs +78 -0
  648. data/core/src/services/sftp/utils.rs +51 -0
  649. data/core/src/services/sftp/writer.rs +67 -0
  650. data/core/src/services/sled/backend.rs +194 -0
  651. data/core/src/services/sled/config.rs +45 -0
  652. data/core/src/services/sled/docs.md +39 -0
  653. data/core/src/services/sled/mod.rs +24 -0
  654. data/core/src/services/sqlite/backend.rs +326 -0
  655. data/core/src/services/sqlite/config.rs +70 -0
  656. data/core/src/services/sqlite/docs.md +46 -0
  657. data/core/src/services/sqlite/mod.rs +24 -0
  658. data/core/src/services/surrealdb/backend.rs +365 -0
  659. data/core/src/services/surrealdb/config.rs +64 -0
  660. data/core/src/services/surrealdb/docs.md +54 -0
  661. data/core/src/services/surrealdb/mod.rs +24 -0
  662. data/core/src/services/swift/backend.rs +275 -0
  663. data/core/src/services/swift/compatible_services.md +53 -0
  664. data/core/src/services/swift/config.rs +53 -0
  665. data/core/src/services/swift/core.rs +310 -0
  666. data/core/src/services/swift/delete.rs +49 -0
  667. data/core/src/services/swift/docs.md +52 -0
  668. data/core/src/services/swift/error.rs +90 -0
  669. data/core/src/services/swift/lister.rs +119 -0
  670. data/core/src/services/swift/mod.rs +38 -0
  671. data/core/src/services/swift/writer.rs +53 -0
  672. data/core/src/services/tikv/backend.rs +237 -0
  673. data/core/src/services/tikv/config.rs +52 -0
  674. data/core/src/services/tikv/docs.md +43 -0
  675. data/core/src/services/tikv/mod.rs +24 -0
  676. data/core/src/services/upyun/backend.rs +317 -0
  677. data/core/src/services/upyun/config.rs +51 -0
  678. data/core/src/services/upyun/core.rs +521 -0
  679. data/core/src/services/upyun/delete.rs +50 -0
  680. data/core/src/services/upyun/docs.md +51 -0
  681. data/core/src/services/upyun/error.rs +97 -0
  682. data/core/src/services/upyun/lister.rs +101 -0
  683. data/core/src/services/upyun/mod.rs +38 -0
  684. data/core/src/services/upyun/writer.rs +127 -0
  685. data/core/src/services/vercel_artifacts/backend.rs +99 -0
  686. data/core/src/services/vercel_artifacts/builder.rs +117 -0
  687. data/core/src/services/vercel_artifacts/config.rs +39 -0
  688. data/core/src/services/vercel_artifacts/core.rs +112 -0
  689. data/core/src/services/vercel_artifacts/docs.md +40 -0
  690. data/core/src/services/vercel_artifacts/error.rs +50 -0
  691. data/core/src/services/vercel_artifacts/mod.rs +36 -0
  692. data/core/src/services/vercel_artifacts/writer.rs +58 -0
  693. data/core/src/services/vercel_blob/backend.rs +251 -0
  694. data/core/src/services/vercel_blob/config.rs +45 -0
  695. data/core/src/services/vercel_blob/core.rs +449 -0
  696. data/core/src/services/vercel_blob/delete.rs +38 -0
  697. data/core/src/services/vercel_blob/docs.md +45 -0
  698. data/core/src/services/vercel_blob/error.rs +110 -0
  699. data/core/src/services/vercel_blob/lister.rs +69 -0
  700. data/core/src/services/vercel_blob/mod.rs +38 -0
  701. data/core/src/services/vercel_blob/writer.rs +143 -0
  702. data/core/src/services/webdav/backend.rs +318 -0
  703. data/core/src/services/webdav/config.rs +53 -0
  704. data/core/src/services/webdav/core.rs +859 -0
  705. data/core/src/services/webdav/delete.rs +47 -0
  706. data/core/src/services/webdav/docs.md +49 -0
  707. data/core/src/services/webdav/error.rs +53 -0
  708. data/core/src/services/webdav/lister.rs +106 -0
  709. data/core/src/services/webdav/mod.rs +38 -0
  710. data/core/src/services/webdav/writer.rs +56 -0
  711. data/core/src/services/webhdfs/backend.rs +376 -0
  712. data/core/src/services/webhdfs/config.rs +52 -0
  713. data/core/src/services/webhdfs/core.rs +398 -0
  714. data/core/src/services/webhdfs/delete.rs +46 -0
  715. data/core/src/services/webhdfs/docs.md +90 -0
  716. data/core/src/services/webhdfs/error.rs +126 -0
  717. data/core/src/services/webhdfs/lister.rs +130 -0
  718. data/core/src/services/webhdfs/message.rs +249 -0
  719. data/core/src/services/webhdfs/mod.rs +41 -0
  720. data/core/src/services/webhdfs/writer.rs +177 -0
  721. data/core/src/services/yandex_disk/backend.rs +267 -0
  722. data/core/src/services/yandex_disk/config.rs +45 -0
  723. data/core/src/services/yandex_disk/core.rs +340 -0
  724. data/core/src/services/yandex_disk/delete.rs +54 -0
  725. data/core/src/services/yandex_disk/docs.md +45 -0
  726. data/core/src/services/yandex_disk/error.rs +104 -0
  727. data/core/src/services/yandex_disk/lister.rs +113 -0
  728. data/core/src/services/yandex_disk/mod.rs +38 -0
  729. data/core/src/services/yandex_disk/writer.rs +52 -0
  730. data/core/src/types/buffer.rs +991 -0
  731. data/core/src/types/builder.rs +152 -0
  732. data/core/src/types/capability.rs +209 -0
  733. data/core/src/types/context/mod.rs +22 -0
  734. data/core/src/types/context/read.rs +231 -0
  735. data/core/src/types/context/write.rs +441 -0
  736. data/core/src/types/delete/deleter.rs +220 -0
  737. data/core/src/types/delete/futures_delete_sink.rs +176 -0
  738. data/core/src/types/delete/input.rs +97 -0
  739. data/core/src/types/delete/mod.rs +26 -0
  740. data/core/src/types/entry.rs +69 -0
  741. data/core/src/types/error.rs +570 -0
  742. data/core/src/types/execute/api.rs +110 -0
  743. data/core/src/types/execute/executor.rs +96 -0
  744. data/core/src/types/execute/executors/mod.rs +27 -0
  745. data/core/src/types/execute/executors/tokio_executor.rs +60 -0
  746. data/core/src/types/execute/mod.rs +25 -0
  747. data/core/src/types/list.rs +137 -0
  748. data/core/src/types/metadata.rs +436 -0
  749. data/core/src/types/mod.rs +72 -0
  750. data/core/src/types/mode.rs +68 -0
  751. data/core/src/types/operator/builder.rs +535 -0
  752. data/core/src/types/operator/info.rs +63 -0
  753. data/core/src/types/operator/mod.rs +33 -0
  754. data/core/src/types/operator/operator.rs +2236 -0
  755. data/core/src/types/operator/operator_futures.rs +1430 -0
  756. data/core/src/types/operator/registry.rs +129 -0
  757. data/core/src/types/options.rs +548 -0
  758. data/core/src/types/read/buffer_stream.rs +273 -0
  759. data/core/src/types/read/futures_async_reader.rs +289 -0
  760. data/core/src/types/read/futures_bytes_stream.rs +157 -0
  761. data/core/src/types/read/mod.rs +29 -0
  762. data/core/src/types/read/reader.rs +604 -0
  763. data/core/src/types/scheme.rs +475 -0
  764. data/core/src/types/write/buffer_sink.rs +188 -0
  765. data/core/src/types/write/futures_async_writer.rs +136 -0
  766. data/core/src/types/write/futures_bytes_sink.rs +103 -0
  767. data/core/src/types/write/mod.rs +26 -0
  768. data/core/src/types/write/writer.rs +411 -0
  769. data/core/tests/behavior/README.md +77 -0
  770. data/core/tests/behavior/async_copy.rs +314 -0
  771. data/core/tests/behavior/async_create_dir.rs +53 -0
  772. data/core/tests/behavior/async_delete.rs +354 -0
  773. data/core/tests/behavior/async_list.rs +739 -0
  774. data/core/tests/behavior/async_presign.rs +175 -0
  775. data/core/tests/behavior/async_read.rs +871 -0
  776. data/core/tests/behavior/async_rename.rs +210 -0
  777. data/core/tests/behavior/async_stat.rs +628 -0
  778. data/core/tests/behavior/async_write.rs +819 -0
  779. data/core/tests/behavior/main.rs +78 -0
  780. data/core/tests/behavior/utils.rs +187 -0
  781. data/core/tests/data/normal_dir/.gitkeep +0 -0
  782. data/core/tests/data/normal_file.txt +1041 -0
  783. data/core/tests/data/special_dir !@#$%^&()_+-=;',/.gitkeep +0 -0
  784. data/core/tests/data/special_file !@#$%^&()_+-=;',.txt +1041 -0
  785. data/core/users.md +13 -0
  786. data/extconf.rb +24 -0
  787. data/lib/opendal.rb +25 -0
  788. data/lib/opendal_ruby/entry.rb +35 -0
  789. data/lib/opendal_ruby/io.rb +70 -0
  790. data/lib/opendal_ruby/metadata.rb +44 -0
  791. data/lib/opendal_ruby/operator.rb +29 -0
  792. data/lib/opendal_ruby/operator_info.rb +26 -0
  793. data/src/capability.rs +146 -0
  794. data/src/io.rs +464 -0
  795. data/src/lib.rs +63 -0
  796. data/src/lister.rs +141 -0
  797. data/src/metadata.rs +111 -0
  798. data/src/middlewares.rs +174 -0
  799. data/src/operator.rs +310 -0
  800. data/src/operator_info.rs +83 -0
  801. data/test/blocking_op_test.rb +112 -0
  802. data/test/capability_test.rb +42 -0
  803. data/test/io_test.rb +172 -0
  804. data/test/lister_test.rb +77 -0
  805. data/test/metadata_test.rb +78 -0
  806. data/test/middlewares_test.rb +46 -0
  807. data/test/operator_info_test.rb +35 -0
  808. data/test/test_helper.rb +36 -0
  809. metadata +857 -0
@@ -0,0 +1,1430 @@
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
+ //! Futures provides the futures generated by [`Operator`]
19
+ //!
20
+ //! By using futures, users can add more options for operation.
21
+
22
+ use std::collections::HashMap;
23
+ use std::future::IntoFuture;
24
+ use std::ops::RangeBounds;
25
+ use std::time::Duration;
26
+
27
+ use chrono::DateTime;
28
+ use chrono::Utc;
29
+ use futures::Future;
30
+
31
+ use crate::raw::*;
32
+ use crate::*;
33
+
34
+ /// OperatorFuture is the future generated by [`Operator`].
35
+ ///
36
+ /// The future will consume all the input to generate a future.
37
+ ///
38
+ /// # NOTES
39
+ ///
40
+ /// This struct is by design to keep in crate. We don't want
41
+ /// users to use this struct directly.
42
+ pub struct OperatorFuture<I, O, F: Future<Output = Result<O>>> {
43
+ /// The accessor to the underlying object storage
44
+ acc: Accessor,
45
+ /// The path of string
46
+ path: String,
47
+ /// The input args
48
+ args: I,
49
+ /// The function which will move all the args and return a static future
50
+ f: fn(Accessor, String, I) -> F,
51
+ }
52
+
53
+ impl<I, O, F: Future<Output = Result<O>>> OperatorFuture<I, O, F> {
54
+ /// # NOTES
55
+ ///
56
+ /// This struct is by design to keep in crate. We don't want
57
+ /// users to use this struct directly.
58
+ pub(crate) fn new(
59
+ inner: Accessor,
60
+ path: String,
61
+ args: I,
62
+ f: fn(Accessor, String, I) -> F,
63
+ ) -> Self {
64
+ OperatorFuture {
65
+ acc: inner,
66
+ path,
67
+ args,
68
+ f,
69
+ }
70
+ }
71
+ }
72
+
73
+ impl<I, O, F> IntoFuture for OperatorFuture<I, O, F>
74
+ where
75
+ F: Future<Output = Result<O>>,
76
+ {
77
+ type Output = Result<O>;
78
+ type IntoFuture = F;
79
+
80
+ fn into_future(self) -> Self::IntoFuture {
81
+ (self.f)(self.acc, self.path, self.args)
82
+ }
83
+ }
84
+
85
+ /// Future that generated by [`Operator::stat_with`].
86
+ ///
87
+ /// Users can add more options by public functions provided by this struct.
88
+ pub type FutureStat<F> = OperatorFuture<options::StatOptions, Metadata, F>;
89
+
90
+ impl<F: Future<Output = Result<Metadata>>> FutureStat<F> {
91
+ /// Set the If-Match for this operation.
92
+ ///
93
+ /// Refer to [`options::StatOptions::if_match`] for more details.
94
+ pub fn if_match(mut self, v: &str) -> Self {
95
+ self.args.if_match = Some(v.to_string());
96
+ self
97
+ }
98
+
99
+ /// Set the If-None-Match for this operation.
100
+ ///
101
+ /// Refer to [`options::StatOptions::if_none_match`] for more details.
102
+ pub fn if_none_match(mut self, v: &str) -> Self {
103
+ self.args.if_none_match = Some(v.to_string());
104
+ self
105
+ }
106
+
107
+ /// Set the If-Modified-Since for this operation.
108
+ ///
109
+ /// Refer to [`options::StatOptions::if_modified_since`] for more details.
110
+ pub fn if_modified_since(mut self, v: DateTime<Utc>) -> Self {
111
+ self.args.if_modified_since = Some(v);
112
+ self
113
+ }
114
+
115
+ /// Set the If-Unmodified-Since for this operation.
116
+ ///
117
+ /// Refer to [`options::StatOptions::if_unmodified_since`] for more details.
118
+ pub fn if_unmodified_since(mut self, v: DateTime<Utc>) -> Self {
119
+ self.args.if_unmodified_since = Some(v);
120
+ self
121
+ }
122
+
123
+ /// Set the version for this operation.
124
+ ///
125
+ /// Refer to [`options::StatOptions::version`] for more details.
126
+ pub fn version(mut self, v: &str) -> Self {
127
+ self.args.version = Some(v.to_string());
128
+ self
129
+ }
130
+ }
131
+
132
+ /// Future that generated by [`Operator::presign_stat_with`].
133
+ ///
134
+ /// Users can add more options by public functions provided by this struct.
135
+ pub type FuturePresignStat<F> =
136
+ OperatorFuture<(options::StatOptions, Duration), PresignedRequest, F>;
137
+
138
+ impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignStat<F> {
139
+ /// Refer to [`options::StatOptions::override_content_disposition`] for more details.
140
+ pub fn override_content_disposition(mut self, v: &str) -> Self {
141
+ self.args.0.override_content_disposition = Some(v.to_string());
142
+ self
143
+ }
144
+
145
+ /// Refer to [`options::StatOptions::override_cache_control`] for more details.
146
+ pub fn override_cache_control(mut self, v: &str) -> Self {
147
+ self.args.0.override_cache_control = Some(v.to_string());
148
+ self
149
+ }
150
+
151
+ /// Refer to [`options::StatOptions::override_content_type`] for more details.
152
+ pub fn override_content_type(mut self, v: &str) -> Self {
153
+ self.args.0.override_content_type = Some(v.to_string());
154
+ self
155
+ }
156
+
157
+ /// Refer to [`options::StatOptions::if_match`] for more details.
158
+ pub fn if_match(mut self, v: &str) -> Self {
159
+ self.args.0.if_match = Some(v.to_string());
160
+ self
161
+ }
162
+
163
+ /// Refer to [`options::StatOptions::if_none_match`] for more details.
164
+ pub fn if_none_match(mut self, v: &str) -> Self {
165
+ self.args.0.if_none_match = Some(v.to_string());
166
+ self
167
+ }
168
+ }
169
+
170
+ /// Future that generated by [`Operator::presign_delete_with`].
171
+ ///
172
+ /// Users can add more options by public functions provided by this struct.
173
+ pub type FuturePresignDelete<F> =
174
+ OperatorFuture<(options::DeleteOptions, Duration), PresignedRequest, F>;
175
+
176
+ impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignDelete<F> {}
177
+
178
+ /// Future that generated by [`Operator::presign_read_with`].
179
+ ///
180
+ /// Users can add more options by public functions provided by this struct.
181
+ pub type FuturePresignRead<F> =
182
+ OperatorFuture<(options::ReadOptions, Duration), PresignedRequest, F>;
183
+
184
+ impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignRead<F> {
185
+ /// Refer to [`options::ReadOptions::override_content_disposition`] for more details.
186
+ pub fn override_content_disposition(mut self, v: &str) -> Self {
187
+ self.args.0.override_content_disposition = Some(v.to_string());
188
+ self
189
+ }
190
+
191
+ /// Refer to [`options::ReadOptions::override_cache_control`] for more details.
192
+ pub fn override_cache_control(mut self, v: &str) -> Self {
193
+ self.args.0.override_cache_control = Some(v.to_string());
194
+ self
195
+ }
196
+
197
+ /// Refer to [`options::ReadOptions::override_content_type`] for more details.
198
+ pub fn override_content_type(mut self, v: &str) -> Self {
199
+ self.args.0.override_content_type = Some(v.to_string());
200
+ self
201
+ }
202
+
203
+ /// Refer to [`options::ReadOptions::if_match`] for more details.
204
+ pub fn if_match(mut self, v: &str) -> Self {
205
+ self.args.0.if_match = Some(v.to_string());
206
+ self
207
+ }
208
+
209
+ /// Refer to [`options::ReadOptions::if_none_match`] for more details.
210
+ pub fn if_none_match(mut self, v: &str) -> Self {
211
+ self.args.0.if_none_match = Some(v.to_string());
212
+ self
213
+ }
214
+ }
215
+
216
+ /// Future that generated by [`Operator::presign_write_with`].
217
+ ///
218
+ /// Users can add more options by public functions provided by this struct.
219
+ pub type FuturePresignWrite<F> =
220
+ OperatorFuture<(options::WriteOptions, Duration), PresignedRequest, F>;
221
+
222
+ impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignWrite<F> {
223
+ /// Refer to [`options::WriteOptions::content_type`] for more details.
224
+ pub fn content_type(mut self, v: &str) -> Self {
225
+ self.args.0.content_type = Some(v.to_string());
226
+ self
227
+ }
228
+
229
+ /// Refer to [`options::WriteOptions::content_disposition`] for more details.
230
+ pub fn content_disposition(mut self, v: &str) -> Self {
231
+ self.args.0.content_disposition = Some(v.to_string());
232
+ self
233
+ }
234
+
235
+ /// Refer to [`options::WriteOptions::content_encoding`] for more details.
236
+ pub fn content_encoding(mut self, v: &str) -> Self {
237
+ self.args.0.content_encoding = Some(v.to_string());
238
+ self
239
+ }
240
+
241
+ /// Refer to [`options::WriteOptions::cache_control`] for more details.
242
+ pub fn cache_control(mut self, v: &str) -> Self {
243
+ self.args.0.cache_control = Some(v.to_string());
244
+ self
245
+ }
246
+ }
247
+
248
+ /// Future that generated by [`Operator::read_with`].
249
+ ///
250
+ /// Users can add more options by public functions provided by this struct.
251
+ pub type FutureRead<F> = OperatorFuture<options::ReadOptions, Buffer, F>;
252
+
253
+ impl<F: Future<Output = Result<Buffer>>> FutureRead<F> {
254
+ /// Set `range` for this `read` request.
255
+ ///
256
+ /// If we have a file with size `n`.
257
+ ///
258
+ /// - `..` means read bytes in range `[0, n)` of file.
259
+ /// - `0..1024` and `..1024` means read bytes in range `[0, 1024)` of file
260
+ /// - `1024..` means read bytes in range `[1024, n)` of file
261
+ ///
262
+ /// ```
263
+ /// # use opendal::Result;
264
+ /// # use opendal::Operator;
265
+ /// # use futures::TryStreamExt;
266
+ /// # async fn test(op: Operator) -> Result<()> {
267
+ /// let bs = op.read_with("path/to/file").range(0..1024).await?;
268
+ /// # Ok(())
269
+ /// # }
270
+ /// ```
271
+ pub fn range(mut self, range: impl RangeBounds<u64>) -> Self {
272
+ self.args.range = range.into();
273
+ self
274
+ }
275
+
276
+ /// Set `concurrent` for the reader.
277
+ ///
278
+ /// OpenDAL by default to write file without concurrent. This is not efficient for cases when users
279
+ /// read large chunks of data. By setting `concurrent`, opendal will read files concurrently
280
+ /// on support storage services.
281
+ ///
282
+ /// By setting `concurrent`, opendal will fetch chunks concurrently with
283
+ /// the given chunk size.
284
+ ///
285
+ /// ```
286
+ /// # use opendal::Result;
287
+ /// # use opendal::Operator;
288
+ /// # use opendal::Scheme;
289
+ /// # async fn test(op: Operator) -> Result<()> {
290
+ /// let r = op.read_with("path/to/file").concurrent(8).await?;
291
+ /// # Ok(())
292
+ /// # }
293
+ /// ```
294
+ pub fn concurrent(mut self, concurrent: usize) -> Self {
295
+ self.args.concurrent = concurrent.max(1);
296
+ self
297
+ }
298
+
299
+ /// OpenDAL will use services' preferred chunk size by default. Users can set chunk based on their own needs.
300
+ ///
301
+ /// This following example will make opendal read data in 4MiB chunks:
302
+ ///
303
+ /// ```
304
+ /// # use opendal::Result;
305
+ /// # use opendal::Operator;
306
+ /// # use opendal::Scheme;
307
+ /// # async fn test(op: Operator) -> Result<()> {
308
+ /// let r = op.read_with("path/to/file").chunk(4 * 1024 * 1024).await?;
309
+ /// # Ok(())
310
+ /// # }
311
+ /// ```
312
+ pub fn chunk(mut self, chunk_size: usize) -> Self {
313
+ self.args.chunk = Some(chunk_size);
314
+ self
315
+ }
316
+
317
+ /// Set `version` for this `read` request.
318
+ ///
319
+ /// This feature can be used to retrieve the data of a specified version of the given path.
320
+ ///
321
+ /// If the version doesn't exist, an error with kind [`ErrorKind::NotFound`] will be returned.
322
+ ///
323
+ /// ```
324
+ /// # use opendal::Result;
325
+ /// # use opendal::Operator;
326
+ ///
327
+ /// # async fn test(op: Operator, version: &str) -> Result<()> {
328
+ /// let mut bs = op.read_with("path/to/file").version(version).await?;
329
+ /// # Ok(())
330
+ /// # }
331
+ /// ```
332
+ pub fn version(mut self, v: &str) -> Self {
333
+ self.args.version = Some(v.to_string());
334
+ self
335
+ }
336
+
337
+ /// Set `if_match` for this `read` request.
338
+ ///
339
+ /// This feature can be used to check if the file's `ETag` matches the given `ETag`.
340
+ ///
341
+ /// If file exists and it's etag doesn't match, an error with kind [`ErrorKind::ConditionNotMatch`]
342
+ /// will be returned.
343
+ ///
344
+ /// ```
345
+ /// # use opendal::Result;
346
+ /// use opendal::Operator;
347
+ /// # async fn test(op: Operator, etag: &str) -> Result<()> {
348
+ /// let mut metadata = op.read_with("path/to/file").if_match(etag).await?;
349
+ /// # Ok(())
350
+ /// # }
351
+ /// ```
352
+ pub fn if_match(mut self, v: &str) -> Self {
353
+ self.args.if_match = Some(v.to_string());
354
+ self
355
+ }
356
+
357
+ /// Set `if_none_match` for this `read` request.
358
+ ///
359
+ /// This feature can be used to check if the file's `ETag` doesn't match the given `ETag`.
360
+ ///
361
+ /// If file exists and it's etag match, an error with kind [`ErrorKind::ConditionNotMatch`]
362
+ /// will be returned.
363
+ ///
364
+ /// ```
365
+ /// # use opendal::Result;
366
+ /// use opendal::Operator;
367
+ /// # async fn test(op: Operator, etag: &str) -> Result<()> {
368
+ /// let mut metadata = op.read_with("path/to/file").if_none_match(etag).await?;
369
+ /// # Ok(())
370
+ /// # }
371
+ /// ```
372
+ pub fn if_none_match(mut self, v: &str) -> Self {
373
+ self.args.if_none_match = Some(v.to_string());
374
+ self
375
+ }
376
+
377
+ /// ## `if_modified_since`
378
+ ///
379
+ /// Set `if_modified_since` for this `read` request.
380
+ ///
381
+ /// This feature can be used to check if the file has been modified since the given timestamp.
382
+ ///
383
+ /// If file exists and it hasn't been modified since the specified time, an error with kind
384
+ /// [`ErrorKind::ConditionNotMatch`] will be returned.
385
+ ///
386
+ /// ```
387
+ /// # use opendal::Result;
388
+ /// use chrono::DateTime;
389
+ /// use chrono::Utc;
390
+ /// use opendal::Operator;
391
+ /// # async fn test(op: Operator, time: DateTime<Utc>) -> Result<()> {
392
+ /// let mut metadata = op.read_with("path/to/file").if_modified_since(time).await?;
393
+ /// # Ok(())
394
+ /// # }
395
+ /// ```
396
+ pub fn if_modified_since(mut self, v: DateTime<Utc>) -> Self {
397
+ self.args.if_modified_since = Some(v);
398
+ self
399
+ }
400
+
401
+ /// Set `if_unmodified_since` for this `read` request.
402
+ ///
403
+ /// This feature can be used to check if the file hasn't been modified since the given timestamp.
404
+ ///
405
+ /// If file exists and it has been modified since the specified time, an error with kind
406
+ /// [`ErrorKind::ConditionNotMatch`] will be returned.
407
+ ///
408
+ /// ```
409
+ /// # use opendal::Result;
410
+ /// use chrono::DateTime;
411
+ /// use chrono::Utc;
412
+ /// use opendal::Operator;
413
+ /// # async fn test(op: Operator, time: DateTime<Utc>) -> Result<()> {
414
+ /// let mut metadata = op
415
+ /// .read_with("path/to/file")
416
+ /// .if_unmodified_since(time)
417
+ /// .await?;
418
+ /// # Ok(())
419
+ /// # }
420
+ /// ```
421
+ pub fn if_unmodified_since(mut self, v: DateTime<Utc>) -> Self {
422
+ self.args.if_unmodified_since = Some(v);
423
+ self
424
+ }
425
+ }
426
+
427
+ /// Future that generated by [`Operator::read_with`] or [`Operator::reader_with`].
428
+ ///
429
+ /// Users can add more options by public functions provided by this struct.
430
+ ///
431
+ /// # Notes
432
+ ///
433
+ /// `(OpRead, ())` is a trick to make sure `FutureReader` is different from `FutureRead`
434
+ pub type FutureReader<F> = OperatorFuture<options::ReaderOptions, Reader, F>;
435
+
436
+ impl<F: Future<Output = Result<Reader>>> FutureReader<F> {
437
+ /// Set `version` for this `reader`.
438
+ ///
439
+ /// This feature can be used to retrieve the data of a specified version of the given path.
440
+ ///
441
+ /// If the version doesn't exist, an error with kind [`ErrorKind::NotFound`] will be returned.
442
+ ///
443
+ /// ```
444
+ /// # use opendal::Result;
445
+ /// # use opendal::Operator;
446
+ ///
447
+ /// # async fn test(op: Operator, version: &str) -> Result<()> {
448
+ /// let mut r = op.reader_with("path/to/file").version(version).await?;
449
+ /// # Ok(())
450
+ /// # }
451
+ /// ```
452
+ pub fn version(mut self, v: &str) -> Self {
453
+ self.args.version = Some(v.to_string());
454
+ self
455
+ }
456
+
457
+ /// Set `concurrent` for the reader.
458
+ ///
459
+ /// OpenDAL by default to write file without concurrent. This is not efficient for cases when users
460
+ /// read large chunks of data. By setting `concurrent`, opendal will reading files concurrently
461
+ /// on support storage services.
462
+ ///
463
+ /// By setting `concurrent`, opendal will fetch chunks concurrently with
464
+ /// the give chunk size.
465
+ ///
466
+ /// ```
467
+ /// # use opendal::Result;
468
+ /// # use opendal::Operator;
469
+ /// # use opendal::Scheme;
470
+ /// # async fn test(op: Operator) -> Result<()> {
471
+ /// let r = op.reader_with("path/to/file").concurrent(8).await?;
472
+ /// # Ok(())
473
+ /// # }
474
+ /// ```
475
+ pub fn concurrent(mut self, concurrent: usize) -> Self {
476
+ self.args.concurrent = concurrent.max(1);
477
+ self
478
+ }
479
+
480
+ /// OpenDAL will use services' preferred chunk size by default. Users can set chunk based on their own needs.
481
+ ///
482
+ /// This following example will make opendal read data in 4MiB chunks:
483
+ ///
484
+ /// ```
485
+ /// # use opendal::Result;
486
+ /// # use opendal::Operator;
487
+ /// # use opendal::Scheme;
488
+ /// # async fn test(op: Operator) -> Result<()> {
489
+ /// let r = op
490
+ /// .reader_with("path/to/file")
491
+ /// .chunk(4 * 1024 * 1024)
492
+ /// .await?;
493
+ /// # Ok(())
494
+ /// # }
495
+ /// ```
496
+ pub fn chunk(mut self, chunk_size: usize) -> Self {
497
+ self.args.chunk = Some(chunk_size);
498
+ self
499
+ }
500
+
501
+ /// Controls the optimization strategy for range reads in [`Reader::fetch`].
502
+ ///
503
+ /// When performing range reads, if the gap between two requested ranges is smaller than
504
+ /// the configured `gap` size, OpenDAL will merge these ranges into a single read request
505
+ /// and discard the unrequested data in between. This helps reduce the number of API calls
506
+ /// to remote storage services.
507
+ ///
508
+ /// This optimization is particularly useful when performing multiple small range reads
509
+ /// that are close to each other, as it reduces the overhead of multiple network requests
510
+ /// at the cost of transferring some additional data.
511
+ ///
512
+ /// In this example, if two requested ranges are separated by less than 1MiB,
513
+ /// they will be merged into a single read request:
514
+ ///
515
+ /// ```
516
+ /// # use opendal::Result;
517
+ /// # use opendal::Operator;
518
+ /// # use opendal::Scheme;
519
+ /// # async fn test(op: Operator) -> Result<()> {
520
+ /// let r = op
521
+ /// .reader_with("path/to/file")
522
+ /// .chunk(4 * 1024 * 1024)
523
+ /// .gap(1024 * 1024) // 1MiB gap
524
+ /// .await?;
525
+ /// # Ok(())
526
+ /// # }
527
+ /// ```
528
+ pub fn gap(mut self, gap_size: usize) -> Self {
529
+ self.args.gap = Some(gap_size);
530
+ self
531
+ }
532
+
533
+ /// Set `if-match` for this `read` request.
534
+ ///
535
+ /// This feature can be used to check if the file's `ETag` matches the given `ETag`.
536
+ ///
537
+ /// If file exists and it's etag doesn't match, an error with kind [`ErrorKind::ConditionNotMatch`]
538
+ /// will be returned.
539
+ ///
540
+ /// ```
541
+ /// # use opendal::Result;
542
+ /// use opendal::Operator;
543
+ /// # async fn test(op: Operator, etag: &str) -> Result<()> {
544
+ /// let mut r = op.reader_with("path/to/file").if_match(etag).await?;
545
+ /// # Ok(())
546
+ /// # }
547
+ /// ```
548
+ pub fn if_match(mut self, etag: &str) -> Self {
549
+ self.args.if_match = Some(etag.to_string());
550
+ self
551
+ }
552
+
553
+ /// Set `if-none-match` for this `read` request.
554
+ ///
555
+ /// This feature can be used to check if the file's `ETag` doesn't match the given `ETag`.
556
+ ///
557
+ /// If file exists and it's etag match, an error with kind [`ErrorKind::ConditionNotMatch`]
558
+ /// will be returned.
559
+ ///
560
+ /// ```
561
+ /// # use opendal::Result;
562
+ /// use opendal::Operator;
563
+ /// # async fn test(op: Operator, etag: &str) -> Result<()> {
564
+ /// let mut r = op.reader_with("path/to/file").if_none_match(etag).await?;
565
+ /// # Ok(())
566
+ /// # }
567
+ /// ```
568
+ pub fn if_none_match(mut self, etag: &str) -> Self {
569
+ self.args.if_none_match = Some(etag.to_string());
570
+ self
571
+ }
572
+
573
+ /// Set `if-modified-since` for this `read` request.
574
+ ///
575
+ /// This feature can be used to check if the file has been modified since the given timestamp.
576
+ ///
577
+ /// If file exists and it hasn't been modified since the specified time, an error with kind
578
+ /// [`ErrorKind::ConditionNotMatch`] will be returned.
579
+ ///
580
+ /// ```
581
+ /// # use opendal::Result;
582
+ /// use chrono::DateTime;
583
+ /// use chrono::Utc;
584
+ /// use opendal::Operator;
585
+ /// # async fn test(op: Operator, time: DateTime<Utc>) -> Result<()> {
586
+ /// let mut r = op
587
+ /// .reader_with("path/to/file")
588
+ /// .if_modified_since(time)
589
+ /// .await?;
590
+ /// # Ok(())
591
+ /// # }
592
+ /// ```
593
+ pub fn if_modified_since(mut self, v: DateTime<Utc>) -> Self {
594
+ self.args.if_modified_since = Some(v);
595
+ self
596
+ }
597
+
598
+ /// Set `if-unmodified-since` for this `read` request.
599
+ ///
600
+ /// This feature can be used to check if the file hasn't been modified since the given timestamp.
601
+ ///
602
+ /// If file exists and it has been modified since the specified time, an error with kind
603
+ /// [`ErrorKind::ConditionNotMatch`] will be returned.
604
+ ///
605
+ /// ```
606
+ /// # use opendal::Result;
607
+ /// use chrono::DateTime;
608
+ /// use chrono::Utc;
609
+ /// use opendal::Operator;
610
+ /// # async fn test(op: Operator, time: DateTime<Utc>) -> Result<()> {
611
+ /// let mut r = op
612
+ /// .reader_with("path/to/file")
613
+ /// .if_unmodified_since(time)
614
+ /// .await?;
615
+ /// # Ok(())
616
+ /// # }
617
+ /// ```
618
+ pub fn if_unmodified_since(mut self, v: DateTime<Utc>) -> Self {
619
+ self.args.if_unmodified_since = Some(v);
620
+ self
621
+ }
622
+ }
623
+
624
+ /// Future that generated by [`Operator::write_with`].
625
+ ///
626
+ /// Users can add more options by public functions provided by this struct.
627
+ pub type FutureWrite<F> = OperatorFuture<(options::WriteOptions, Buffer), Metadata, F>;
628
+
629
+ impl<F: Future<Output = Result<Metadata>>> FutureWrite<F> {
630
+ /// Sets append mode for this write request.
631
+ ///
632
+ /// Refer to [`options::WriteOptions::append`] for more details.
633
+ ///
634
+ /// ### Example
635
+ ///
636
+ /// ```
637
+ /// # use opendal::Result;
638
+ /// # use opendal::Operator;
639
+ /// # use futures::StreamExt;
640
+ /// # use futures::SinkExt;
641
+ /// use bytes::Bytes;
642
+ ///
643
+ /// # async fn test(op: Operator) -> Result<()> {
644
+ /// let _ = op
645
+ /// .write_with("path/to/file", vec![0; 4096])
646
+ /// .append(true)
647
+ /// .await?;
648
+ /// # Ok(())
649
+ /// # }
650
+ /// ```
651
+ pub fn append(mut self, v: bool) -> Self {
652
+ self.args.0.append = v;
653
+ self
654
+ }
655
+
656
+ /// Sets chunk size for buffered writes.
657
+ ///
658
+ /// Refer to [`options::WriteOptions::chunk`] for more details.
659
+ ///
660
+ /// ### Example
661
+ ///
662
+ /// ```
663
+ /// # use opendal::Result;
664
+ /// # use opendal::Operator;
665
+ /// # use futures::StreamExt;
666
+ /// # use futures::SinkExt;
667
+ /// use bytes::Bytes;
668
+ ///
669
+ /// # async fn test(op: Operator) -> Result<()> {
670
+ /// // Set 8MiB chunk size - data will be sent in one API call at close
671
+ /// let _ = op
672
+ /// .write_with("path/to/file", vec![0; 4096])
673
+ /// .chunk(8 * 1024 * 1024)
674
+ /// .await?;
675
+ /// # Ok(())
676
+ /// # }
677
+ /// ```
678
+ pub fn chunk(mut self, v: usize) -> Self {
679
+ self.args.0.chunk = Some(v);
680
+ self
681
+ }
682
+
683
+ /// Sets concurrent write operations for this writer.
684
+ ///
685
+ /// Refer to [`options::WriteOptions::concurrent`] for more details.
686
+ ///
687
+ /// ## Example
688
+ ///
689
+ /// ```
690
+ /// # use opendal::Result;
691
+ /// # use opendal::Operator;
692
+ /// # use futures::StreamExt;
693
+ /// # use futures::SinkExt;
694
+ /// use bytes::Bytes;
695
+ ///
696
+ /// # async fn test(op: Operator) -> Result<()> {
697
+ /// // Enable concurrent writes with 8 parallel operations at 128B chunk.
698
+ /// let _ = op
699
+ /// .write_with("path/to/file", vec![0; 4096])
700
+ /// .chunk(128)
701
+ /// .concurrent(8)
702
+ /// .await?;
703
+ /// # Ok(())
704
+ /// # }
705
+ /// ```
706
+ pub fn concurrent(mut self, v: usize) -> Self {
707
+ self.args.0.concurrent = v.max(1);
708
+ self
709
+ }
710
+
711
+ /// Sets Cache-Control header for this write operation.
712
+ ///
713
+ /// Refer to [`options::WriteOptions::cache_control`] for more details.
714
+ ///
715
+ /// ### Example
716
+ ///
717
+ /// ```
718
+ /// # use opendal::Result;
719
+ /// # use opendal::Operator;
720
+ /// # use futures::StreamExt;
721
+ /// # use futures::SinkExt;
722
+ /// use bytes::Bytes;
723
+ ///
724
+ /// # async fn test(op: Operator) -> Result<()> {
725
+ /// // Cache content for 7 days (604800 seconds)
726
+ /// let _ = op
727
+ /// .write_with("path/to/file", vec![0; 4096])
728
+ /// .cache_control("max-age=604800")
729
+ /// .await?;
730
+ /// # Ok(())
731
+ /// # }
732
+ /// ```
733
+ pub fn cache_control(mut self, v: &str) -> Self {
734
+ self.args.0.cache_control = Some(v.to_string());
735
+ self
736
+ }
737
+
738
+ /// Sets `Content-Type` header for this write operation.
739
+ ///
740
+ /// Refer to [`options::WriteOptions::content_type`] for more details.
741
+ ///
742
+ /// ## Example
743
+ ///
744
+ /// ```
745
+ /// # use opendal::Result;
746
+ /// # use opendal::Operator;
747
+ /// use bytes::Bytes;
748
+ ///
749
+ /// # async fn test(op: Operator) -> Result<()> {
750
+ /// // Set content type for plain text file
751
+ /// let _ = op
752
+ /// .write_with("path/to/file", vec![0; 4096])
753
+ /// .content_type("text/plain")
754
+ /// .await?;
755
+ /// # Ok(())
756
+ /// # }
757
+ /// ```
758
+ pub fn content_type(mut self, v: &str) -> Self {
759
+ self.args.0.content_type = Some(v.to_string());
760
+ self
761
+ }
762
+
763
+ /// Sets Content-Disposition header for this write request.
764
+ ///
765
+ /// Refer to [`options::WriteOptions::content_disposition`] for more details.
766
+ ///
767
+ /// ### Example
768
+ ///
769
+ /// ```
770
+ /// # use opendal::Result;
771
+ /// # use opendal::Operator;
772
+ /// # use futures::StreamExt;
773
+ /// # use futures::SinkExt;
774
+ /// use bytes::Bytes;
775
+ ///
776
+ /// # async fn test(op: Operator) -> Result<()> {
777
+ /// let _ = op
778
+ /// .write_with("path/to/file", vec![0; 4096])
779
+ /// .content_disposition("attachment; filename=\"filename.jpg\"")
780
+ /// .await?;
781
+ /// # Ok(())
782
+ /// # }
783
+ /// ```
784
+ pub fn content_disposition(mut self, v: &str) -> Self {
785
+ self.args.0.content_disposition = Some(v.to_string());
786
+ self
787
+ }
788
+
789
+ /// Sets Content-Encoding header for this write request.
790
+ ///
791
+ /// Refer to [`options::WriteOptions::content_encoding`] for more details.
792
+ ///
793
+ /// ### Example
794
+ ///
795
+ /// ```
796
+ /// # use opendal::Result;
797
+ /// # use opendal::Operator;
798
+ /// # use futures::StreamExt;
799
+ /// # use futures::SinkExt;
800
+ /// use bytes::Bytes;
801
+ ///
802
+ /// # async fn test(op: Operator) -> Result<()> {
803
+ /// let _ = op
804
+ /// .write_with("path/to/file", vec![0; 4096])
805
+ /// .content_encoding("gzip")
806
+ /// .await?;
807
+ /// # Ok(())
808
+ /// # }
809
+ /// ```
810
+ pub fn content_encoding(mut self, v: &str) -> Self {
811
+ self.args.0.content_encoding = Some(v.to_string());
812
+ self
813
+ }
814
+
815
+ /// Sets If-Match header for this write request.
816
+ ///
817
+ /// Refer to [`options::WriteOptions::if_match`] for more details.
818
+ ///
819
+ /// ### Example
820
+ ///
821
+ /// ```
822
+ /// # use opendal::Result;
823
+ /// # use opendal::Operator;
824
+ /// # use futures::StreamExt;
825
+ /// # use futures::SinkExt;
826
+ /// use bytes::Bytes;
827
+ ///
828
+ /// # async fn test(op: Operator) -> Result<()> {
829
+ /// let _ = op
830
+ /// .write_with("path/to/file", vec![0; 4096])
831
+ /// .if_match("\"686897696a7c876b7e\"")
832
+ /// .await?;
833
+ /// # Ok(())
834
+ /// # }
835
+ /// ```
836
+ pub fn if_match(mut self, s: &str) -> Self {
837
+ self.args.0.if_match = Some(s.to_string());
838
+ self
839
+ }
840
+
841
+ /// Sets If-None-Match header for this write request.
842
+ ///
843
+ /// Refer to [`options::WriteOptions::if_none_match`] for more details.
844
+ ///
845
+ /// ### Example
846
+ ///
847
+ /// ```
848
+ /// # use opendal::Result;
849
+ /// # use opendal::Operator;
850
+ /// # use futures::StreamExt;
851
+ /// # use futures::SinkExt;
852
+ /// use bytes::Bytes;
853
+ ///
854
+ /// # async fn test(op: Operator) -> Result<()> {
855
+ /// let _ = op
856
+ /// .write_with("path/to/file", vec![0; 4096])
857
+ /// .if_none_match("\"686897696a7c876b7e\"")
858
+ /// .await?;
859
+ /// # Ok(())
860
+ /// # }
861
+ /// ```
862
+ pub fn if_none_match(mut self, s: &str) -> Self {
863
+ self.args.0.if_none_match = Some(s.to_string());
864
+ self
865
+ }
866
+
867
+ /// Sets the condition that write operation will succeed only if target does not exist.
868
+ ///
869
+ /// Refer to [`options::WriteOptions::if_not_exists`] for more details.
870
+ ///
871
+ /// ### Example
872
+ ///
873
+ /// ```
874
+ /// # use opendal::Result;
875
+ /// # use opendal::Operator;
876
+ /// # use futures::StreamExt;
877
+ /// # use futures::SinkExt;
878
+ /// use bytes::Bytes;
879
+ ///
880
+ /// # async fn test(op: Operator) -> Result<()> {
881
+ /// let _ = op
882
+ /// .write_with("path/to/file", vec![0; 4096])
883
+ /// .if_not_exists(true)
884
+ /// .await?;
885
+ /// # Ok(())
886
+ /// # }
887
+ /// ```
888
+ pub fn if_not_exists(mut self, b: bool) -> Self {
889
+ self.args.0.if_not_exists = b;
890
+ self
891
+ }
892
+
893
+ /// Sets user metadata for this write request.
894
+ ///
895
+ /// Refer to [`options::WriteOptions::user_metadata`] for more details.
896
+ ///
897
+ /// ### Example
898
+ ///
899
+ /// ```
900
+ /// # use opendal::Result;
901
+ /// # use opendal::Operator;
902
+ /// # use futures::StreamExt;
903
+ /// # use futures::SinkExt;
904
+ /// use bytes::Bytes;
905
+ ///
906
+ /// # async fn test(op: Operator) -> Result<()> {
907
+ /// let _ = op
908
+ /// .write_with("path/to/file", vec![0; 4096])
909
+ /// .user_metadata([
910
+ /// ("language".to_string(), "rust".to_string()),
911
+ /// ("author".to_string(), "OpenDAL".to_string()),
912
+ /// ])
913
+ /// .await?;
914
+ /// # Ok(())
915
+ /// # }
916
+ /// ```
917
+ pub fn user_metadata(mut self, data: impl IntoIterator<Item = (String, String)>) -> Self {
918
+ self.args.0.user_metadata = Some(HashMap::from_iter(data));
919
+ self
920
+ }
921
+ }
922
+
923
+ /// Future that generated by [`Operator::writer_with`].
924
+ ///
925
+ /// Users can add more options by public functions provided by this struct.
926
+ pub type FutureWriter<F> = OperatorFuture<options::WriteOptions, Writer, F>;
927
+
928
+ impl<F: Future<Output = Result<Writer>>> FutureWriter<F> {
929
+ /// Sets append mode for this write request.
930
+ ///
931
+ /// Refer to [`options::WriteOptions::append`] for more details.
932
+ ///
933
+ /// ### Example
934
+ ///
935
+ /// ```
936
+ /// # use opendal::Result;
937
+ /// # use opendal::Operator;
938
+ /// # use futures::StreamExt;
939
+ /// # use futures::SinkExt;
940
+ /// use bytes::Bytes;
941
+ ///
942
+ /// # async fn test(op: Operator) -> Result<()> {
943
+ /// let mut w = op.writer_with("path/to/file").append(true).await?;
944
+ /// w.write(vec![0; 4096]).await?;
945
+ /// w.write(vec![1; 4096]).await?;
946
+ /// w.close().await?;
947
+ /// # Ok(())
948
+ /// # }
949
+ /// ```
950
+ pub fn append(mut self, v: bool) -> Self {
951
+ self.args.append = v;
952
+ self
953
+ }
954
+
955
+ /// Sets chunk size for buffered writes.
956
+ ///
957
+ /// Refer to [`options::WriteOptions::chunk`] for more details.
958
+ ///
959
+ /// ### Example
960
+ ///
961
+ /// ```
962
+ /// # use opendal::Result;
963
+ /// # use opendal::Operator;
964
+ /// # use futures::StreamExt;
965
+ /// # use futures::SinkExt;
966
+ /// use bytes::Bytes;
967
+ ///
968
+ /// # async fn test(op: Operator) -> Result<()> {
969
+ /// // Set 8MiB chunk size - data will be sent in one API call at close
970
+ /// let mut w = op
971
+ /// .writer_with("path/to/file")
972
+ /// .chunk(8 * 1024 * 1024)
973
+ /// .await?;
974
+ /// w.write(vec![0; 4096]).await?;
975
+ /// w.write(vec![1; 4096]).await?;
976
+ /// w.close().await?;
977
+ /// # Ok(())
978
+ /// # }
979
+ /// ```
980
+ pub fn chunk(mut self, v: usize) -> Self {
981
+ self.args.chunk = Some(v);
982
+ self
983
+ }
984
+
985
+ /// Sets concurrent write operations for this writer.
986
+ ///
987
+ /// Refer to [`options::WriteOptions::concurrent`] for more details.
988
+ ///
989
+ /// ## Example
990
+ ///
991
+ /// ```
992
+ /// # use opendal::Result;
993
+ /// # use opendal::Operator;
994
+ /// # use futures::StreamExt;
995
+ /// # use futures::SinkExt;
996
+ /// use bytes::Bytes;
997
+ ///
998
+ /// # async fn test(op: Operator) -> Result<()> {
999
+ /// // Enable concurrent writes with 8 parallel operations
1000
+ /// let mut w = op.writer_with("path/to/file").concurrent(8).await?;
1001
+ ///
1002
+ /// // First write starts immediately
1003
+ /// w.write(vec![0; 4096]).await?;
1004
+ ///
1005
+ /// // Second write runs concurrently with first
1006
+ /// w.write(vec![1; 4096]).await?;
1007
+ ///
1008
+ /// // Ensures all writes complete successfully and in order
1009
+ /// w.close().await?;
1010
+ /// # Ok(())
1011
+ /// # }
1012
+ /// ```
1013
+ pub fn concurrent(mut self, v: usize) -> Self {
1014
+ self.args.concurrent = v.max(1);
1015
+ self
1016
+ }
1017
+
1018
+ /// Sets Cache-Control header for this write operation.
1019
+ ///
1020
+ /// Refer to [`options::WriteOptions::cache_control`] for more details.
1021
+ ///
1022
+ /// ### Example
1023
+ ///
1024
+ /// ```
1025
+ /// # use opendal::Result;
1026
+ /// # use opendal::Operator;
1027
+ /// # use futures::StreamExt;
1028
+ /// # use futures::SinkExt;
1029
+ /// use bytes::Bytes;
1030
+ ///
1031
+ /// # async fn test(op: Operator) -> Result<()> {
1032
+ /// // Cache content for 7 days (604800 seconds)
1033
+ /// let mut w = op
1034
+ /// .writer_with("path/to/file")
1035
+ /// .cache_control("max-age=604800")
1036
+ /// .await?;
1037
+ /// w.write(vec![0; 4096]).await?;
1038
+ /// w.write(vec![1; 4096]).await?;
1039
+ /// w.close().await?;
1040
+ /// # Ok(())
1041
+ /// # }
1042
+ /// ```
1043
+ pub fn cache_control(mut self, v: &str) -> Self {
1044
+ self.args.cache_control = Some(v.to_string());
1045
+ self
1046
+ }
1047
+
1048
+ /// Sets `Content-Type` header for this write operation.
1049
+ ///
1050
+ /// Refer to [`options::WriteOptions::content_type`] for more details.
1051
+ ///
1052
+ /// ## Example
1053
+ ///
1054
+ /// ```
1055
+ /// # use opendal::Result;
1056
+ /// # use opendal::Operator;
1057
+ /// use bytes::Bytes;
1058
+ ///
1059
+ /// # async fn test(op: Operator) -> Result<()> {
1060
+ /// // Set content type for plain text file
1061
+ /// let mut w = op
1062
+ /// .writer_with("path/to/file")
1063
+ /// .content_type("text/plain")
1064
+ /// .await?;
1065
+ /// w.write(vec![0; 4096]).await?;
1066
+ /// w.write(vec![1; 4096]).await?;
1067
+ /// w.close().await?;
1068
+ /// # Ok(())
1069
+ /// # }
1070
+ /// ```
1071
+ pub fn content_type(mut self, v: &str) -> Self {
1072
+ self.args.content_type = Some(v.to_string());
1073
+ self
1074
+ }
1075
+
1076
+ /// Sets Content-Disposition header for this write request.
1077
+ ///
1078
+ /// Refer to [`options::WriteOptions::content_disposition`] for more details.
1079
+ ///
1080
+ /// ### Example
1081
+ ///
1082
+ /// ```
1083
+ /// # use opendal::Result;
1084
+ /// # use opendal::Operator;
1085
+ /// # use futures::StreamExt;
1086
+ /// # use futures::SinkExt;
1087
+ /// use bytes::Bytes;
1088
+ ///
1089
+ /// # async fn test(op: Operator) -> Result<()> {
1090
+ /// let mut w = op
1091
+ /// .writer_with("path/to/file")
1092
+ /// .content_disposition("attachment; filename=\"filename.jpg\"")
1093
+ /// .await?;
1094
+ /// w.write(vec![0; 4096]).await?;
1095
+ /// w.write(vec![1; 4096]).await?;
1096
+ /// w.close().await?;
1097
+ /// # Ok(())
1098
+ /// # }
1099
+ /// ```
1100
+ pub fn content_disposition(mut self, v: &str) -> Self {
1101
+ self.args.content_disposition = Some(v.to_string());
1102
+ self
1103
+ }
1104
+
1105
+ /// Sets Content-Encoding header for this write request.
1106
+ ///
1107
+ /// Refer to [`options::WriteOptions::content_encoding`] for more details.
1108
+ ///
1109
+ /// ### Example
1110
+ ///
1111
+ /// ```
1112
+ /// # use opendal::Result;
1113
+ /// # use opendal::Operator;
1114
+ /// # use futures::StreamExt;
1115
+ /// # use futures::SinkExt;
1116
+ /// use bytes::Bytes;
1117
+ ///
1118
+ /// # async fn test(op: Operator) -> Result<()> {
1119
+ /// let mut w = op
1120
+ /// .writer_with("path/to/file")
1121
+ /// .content_encoding("gzip")
1122
+ /// .await?;
1123
+ /// w.write(vec![0; 4096]).await?;
1124
+ /// w.write(vec![1; 4096]).await?;
1125
+ /// w.close().await?;
1126
+ /// # Ok(())
1127
+ /// # }
1128
+ /// ```
1129
+ pub fn content_encoding(mut self, v: &str) -> Self {
1130
+ self.args.content_encoding = Some(v.to_string());
1131
+ self
1132
+ }
1133
+
1134
+ /// Sets If-Match header for this write request.
1135
+ ///
1136
+ /// Refer to [`options::WriteOptions::if_match`] for more details.
1137
+ ///
1138
+ /// ### Behavior
1139
+ ///
1140
+ /// - If supported, the write operation will only succeed if the target's ETag matches the specified value
1141
+ /// - The value should be a valid ETag string
1142
+ /// - Common values include:
1143
+ /// - A specific ETag value like `"686897696a7c876b7e"`
1144
+ /// - `*` - Matches any existing resource
1145
+ /// - If not supported, the value will be ignored
1146
+ ///
1147
+ /// This operation provides conditional write functionality based on ETag matching,
1148
+ /// helping prevent unintended overwrites in concurrent scenarios.
1149
+ ///
1150
+ /// ### Example
1151
+ ///
1152
+ /// ```
1153
+ /// # use opendal::Result;
1154
+ /// # use opendal::Operator;
1155
+ /// # use futures::StreamExt;
1156
+ /// # use futures::SinkExt;
1157
+ /// use bytes::Bytes;
1158
+ ///
1159
+ /// # async fn test(op: Operator) -> Result<()> {
1160
+ /// let mut w = op
1161
+ /// .writer_with("path/to/file")
1162
+ /// .if_match("\"686897696a7c876b7e\"")
1163
+ /// .await?;
1164
+ /// w.write(vec![0; 4096]).await?;
1165
+ /// w.write(vec![1; 4096]).await?;
1166
+ /// w.close().await?;
1167
+ /// # Ok(())
1168
+ /// # }
1169
+ /// ```
1170
+ pub fn if_match(mut self, s: &str) -> Self {
1171
+ self.args.if_match = Some(s.to_string());
1172
+ self
1173
+ }
1174
+
1175
+ /// Sets If-None-Match header for this write request.
1176
+ ///
1177
+ /// Refer to [`options::WriteOptions::if_none_match`] for more details.
1178
+ ///
1179
+ /// ### Example
1180
+ ///
1181
+ /// ```
1182
+ /// # use opendal::Result;
1183
+ /// # use opendal::Operator;
1184
+ /// # use futures::StreamExt;
1185
+ /// # use futures::SinkExt;
1186
+ /// use bytes::Bytes;
1187
+ ///
1188
+ /// # async fn test(op: Operator) -> Result<()> {
1189
+ /// let mut w = op
1190
+ /// .writer_with("path/to/file")
1191
+ /// .if_none_match("\"686897696a7c876b7e\"")
1192
+ /// .await?;
1193
+ /// w.write(vec![0; 4096]).await?;
1194
+ /// w.write(vec![1; 4096]).await?;
1195
+ /// w.close().await?;
1196
+ /// # Ok(())
1197
+ /// # }
1198
+ /// ```
1199
+ pub fn if_none_match(mut self, s: &str) -> Self {
1200
+ self.args.if_none_match = Some(s.to_string());
1201
+ self
1202
+ }
1203
+
1204
+ /// Sets the condition that write operation will succeed only if target does not exist.
1205
+ ///
1206
+ /// Refer to [`options::WriteOptions::if_not_exists`] for more details.
1207
+ ///
1208
+ /// ### Example
1209
+ ///
1210
+ /// ```
1211
+ /// # use opendal::Result;
1212
+ /// # use opendal::Operator;
1213
+ /// # use futures::StreamExt;
1214
+ /// # use futures::SinkExt;
1215
+ /// use bytes::Bytes;
1216
+ ///
1217
+ /// # async fn test(op: Operator) -> Result<()> {
1218
+ /// let mut w = op.writer_with("path/to/file").if_not_exists(true).await?;
1219
+ /// w.write(vec![0; 4096]).await?;
1220
+ /// w.write(vec![1; 4096]).await?;
1221
+ /// w.close().await?;
1222
+ /// # Ok(())
1223
+ /// # }
1224
+ /// ```
1225
+ pub fn if_not_exists(mut self, b: bool) -> Self {
1226
+ self.args.if_not_exists = b;
1227
+ self
1228
+ }
1229
+
1230
+ /// Sets user metadata for this write request.
1231
+ ///
1232
+ /// Refer to [`options::WriteOptions::user_metadata`] for more details.
1233
+ ///
1234
+ /// ### Example
1235
+ ///
1236
+ /// ```
1237
+ /// # use opendal::Result;
1238
+ /// # use opendal::Operator;
1239
+ /// # use futures::StreamExt;
1240
+ /// # use futures::SinkExt;
1241
+ /// use bytes::Bytes;
1242
+ ///
1243
+ /// # async fn test(op: Operator) -> Result<()> {
1244
+ /// let mut w = op
1245
+ /// .writer_with("path/to/file")
1246
+ /// .user_metadata([
1247
+ /// ("content-type".to_string(), "text/plain".to_string()),
1248
+ /// ("author".to_string(), "OpenDAL".to_string()),
1249
+ /// ])
1250
+ /// .await?;
1251
+ /// w.write(vec![0; 4096]).await?;
1252
+ /// w.close().await?;
1253
+ /// # Ok(())
1254
+ /// # }
1255
+ /// ```
1256
+ pub fn user_metadata(mut self, data: impl IntoIterator<Item = (String, String)>) -> Self {
1257
+ self.args.user_metadata = Some(HashMap::from_iter(data));
1258
+ self
1259
+ }
1260
+ }
1261
+
1262
+ /// Future that generated by [`Operator::delete_with`].
1263
+ ///
1264
+ /// Users can add more options by public functions provided by this struct.
1265
+ pub type FutureDelete<F> = OperatorFuture<options::DeleteOptions, (), F>;
1266
+
1267
+ impl<F: Future<Output = Result<()>>> FutureDelete<F> {
1268
+ /// Change the version of this delete operation.
1269
+ pub fn version(mut self, v: &str) -> Self {
1270
+ self.args.version = Some(v.to_string());
1271
+ self
1272
+ }
1273
+ }
1274
+
1275
+ /// Future that generated by [`Operator::deleter_with`].
1276
+ ///
1277
+ /// Users can add more options by public functions provided by this struct.
1278
+ pub type FutureDeleter<F> = OperatorFuture<OpDeleter, (), F>;
1279
+
1280
+ /// Future that generated by [`Operator::list_with`] or [`Operator::lister_with`].
1281
+ ///
1282
+ /// Users can add more options by public functions provided by this struct.
1283
+ pub type FutureList<F> = OperatorFuture<options::ListOptions, Vec<Entry>, F>;
1284
+
1285
+ impl<F: Future<Output = Result<Vec<Entry>>>> FutureList<F> {
1286
+ /// The limit passed to underlying service to specify the max results
1287
+ /// that could return per-request.
1288
+ ///
1289
+ /// Users could use this to control the memory usage of list operation.
1290
+ pub fn limit(mut self, v: usize) -> Self {
1291
+ self.args.limit = Some(v);
1292
+ self
1293
+ }
1294
+
1295
+ /// The start_after passes to underlying service to specify the specified key
1296
+ /// to start listing from.
1297
+ pub fn start_after(mut self, v: &str) -> Self {
1298
+ self.args.start_after = Some(v.to_string());
1299
+ self
1300
+ }
1301
+
1302
+ /// The recursive is used to control whether the list operation is recursive.
1303
+ ///
1304
+ /// - If `false`, list operation will only list the entries under the given path.
1305
+ /// - If `true`, list operation will list all entries that starts with given path.
1306
+ ///
1307
+ /// Default to `false`.
1308
+ pub fn recursive(mut self, v: bool) -> Self {
1309
+ self.args.recursive = v;
1310
+ self
1311
+ }
1312
+
1313
+ /// Controls whether the `list` operation should return file versions.
1314
+ ///
1315
+ /// This function allows you to specify if the `list` operation, when executed, should include
1316
+ /// information about different versions of files, if versioning is supported and enabled.
1317
+ ///
1318
+ /// If `true`, subsequent `list` operations will include version information for each file.
1319
+ /// If `false`, version information will be omitted from the `list` results.
1320
+ ///
1321
+ /// Default to `false`
1322
+ pub fn versions(mut self, v: bool) -> Self {
1323
+ self.args.versions = v;
1324
+ self
1325
+ }
1326
+
1327
+ /// Controls whether the `list` operation should include deleted files (or versions).
1328
+ ///
1329
+ /// This function allows you to specify if the `list` operation, when executed, should include
1330
+ /// entries for files or versions that have been marked as deleted. This is particularly relevant
1331
+ /// in object storage systems that support soft deletion or versioning.
1332
+ ///
1333
+ /// If `true`, subsequent `list` operations will include deleted files or versions.
1334
+ /// If `false`, deleted files or versions will be excluded from the `list` results.
1335
+ pub fn deleted(mut self, v: bool) -> Self {
1336
+ self.args.deleted = v;
1337
+ self
1338
+ }
1339
+ }
1340
+
1341
+ /// Future that generated by [`Operator::list_with`] or [`Operator::lister_with`].
1342
+ ///
1343
+ /// Users can add more options by public functions provided by this struct.
1344
+ pub type FutureLister<F> = OperatorFuture<options::ListOptions, Lister, F>;
1345
+
1346
+ impl<F: Future<Output = Result<Lister>>> FutureLister<F> {
1347
+ /// The limit passed to underlying service to specify the max results
1348
+ /// that could return per-request.
1349
+ ///
1350
+ /// Users could use this to control the memory usage of list operation.
1351
+ pub fn limit(mut self, v: usize) -> Self {
1352
+ self.args.limit = Some(v);
1353
+ self
1354
+ }
1355
+
1356
+ /// The start_after passes to underlying service to specify the specified key
1357
+ /// to start listing from.
1358
+ pub fn start_after(mut self, v: &str) -> Self {
1359
+ self.args.start_after = Some(v.to_string());
1360
+ self
1361
+ }
1362
+
1363
+ /// The recursive is used to control whether the list operation is recursive.
1364
+ ///
1365
+ /// - If `false`, list operation will only list the entries under the given path.
1366
+ /// - If `true`, list operation will list all entries that starts with given path.
1367
+ ///
1368
+ /// Default to `false`.
1369
+ pub fn recursive(mut self, v: bool) -> Self {
1370
+ self.args.recursive = v;
1371
+ self
1372
+ }
1373
+
1374
+ /// Controls whether the `list` operation should return file versions.
1375
+ ///
1376
+ /// This function allows you to specify if the `list` operation, when executed, should include
1377
+ /// information about different versions of files, if versioning is supported and enabled.
1378
+ ///
1379
+ /// If `true`, subsequent `list` operations will include version information for each file.
1380
+ /// If `false`, version information will be omitted from the `list` results.
1381
+ ///
1382
+ /// Default to `false`
1383
+ pub fn versions(mut self, v: bool) -> Self {
1384
+ self.args.versions = v;
1385
+ self
1386
+ }
1387
+
1388
+ /// Controls whether the `list` operation should include deleted files (or versions).
1389
+ ///
1390
+ /// This function allows you to specify if the `list` operation, when executed, should include
1391
+ /// entries for files or versions that have been marked as deleted. This is particularly relevant
1392
+ /// in object storage systems that support soft deletion or versioning.
1393
+ ///
1394
+ /// If `true`, subsequent `list` operations will include deleted files or versions.
1395
+ /// If `false`, deleted files or versions will be excluded from the `list` results.
1396
+ pub fn deleted(mut self, v: bool) -> Self {
1397
+ self.args.deleted = v;
1398
+ self
1399
+ }
1400
+ }
1401
+
1402
+ /// Future that generated by [`Operator::copy_with`].
1403
+ ///
1404
+ /// Users can add more options by public functions provided by this struct.
1405
+ pub type FutureCopy<F> = OperatorFuture<(options::CopyOptions, String), (), F>;
1406
+
1407
+ impl<F: Future<Output = Result<()>>> FutureCopy<F> {
1408
+ /// Sets the condition that copy operation will succeed only if target does not exist.
1409
+ ///
1410
+ /// Refer to [`options::CopyOptions::if_not_exists`] for more details.
1411
+ ///
1412
+ /// ### Example
1413
+ ///
1414
+ /// ```
1415
+ /// # use opendal::Result;
1416
+ /// # use opendal::Operator;
1417
+ ///
1418
+ /// # async fn test(op: Operator) -> Result<()> {
1419
+ /// let _ = op
1420
+ /// .copy_with("source/path", "target/path")
1421
+ /// .if_not_exists(true)
1422
+ /// .await?;
1423
+ /// # Ok(())
1424
+ /// # }
1425
+ /// ```
1426
+ pub fn if_not_exists(mut self, v: bool) -> Self {
1427
+ self.args.0.if_not_exists = v;
1428
+ self
1429
+ }
1430
+ }