opendal 0.1.9 → 0.1.11

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 (566) hide show
  1. checksums.yaml +4 -4
  2. data/Cargo.lock +89 -56
  3. data/Cargo.toml +1 -1
  4. data/DEPENDENCIES.rust.tsv +55 -41
  5. data/LICENSE +201 -0
  6. data/LICENSE-MPL-2.0.txt +373 -0
  7. data/NOTICE +5 -0
  8. data/core/CHANGELOG.md +175 -0
  9. data/core/Cargo.lock +225 -298
  10. data/core/Cargo.toml +100 -94
  11. data/core/DEPENDENCIES.rust.tsv +44 -73
  12. data/core/benches/metadata/README.md +21 -0
  13. data/core/benches/metadata/main.rs +541 -0
  14. data/core/benches/vs_fs/Cargo.toml +1 -1
  15. data/core/benches/vs_s3/Cargo.toml +1 -1
  16. data/core/core/Cargo.toml +7 -2
  17. data/core/core/src/blocking/delete.rs +5 -1
  18. data/core/core/src/blocking/operator.rs +12 -0
  19. data/core/core/src/blocking/read/std_reader.rs +25 -0
  20. data/core/core/src/docs/concepts.rs +70 -94
  21. data/core/core/src/docs/internals/accessor.rs +62 -293
  22. data/core/core/src/docs/internals/layer.rs +43 -59
  23. data/core/core/src/docs/internals/mod.rs +21 -23
  24. data/core/core/src/docs/mod.rs +10 -6
  25. data/core/core/src/docs/performance/concurrent_write.md +92 -55
  26. data/core/core/src/docs/performance/http_optimization.md +120 -104
  27. data/core/core/src/docs/performance/mod.rs +8 -6
  28. data/core/core/src/docs/rfcs/5485_conditional_reader.md +4 -0
  29. data/core/core/src/docs/rfcs/7182_restore_api.md +139 -557
  30. data/core/core/src/docs/rfcs/7945_limited_read.md +210 -0
  31. data/core/core/src/docs/rfcs/7948_s3_provider_presets.md +254 -0
  32. data/core/core/src/docs/rfcs/8109_writer_copy_from.md +330 -0
  33. data/core/core/src/docs/rfcs/8145_conflict_error_kind.md +210 -0
  34. data/core/core/src/docs/rfcs/8147_write_if_not_changed.md +233 -0
  35. data/core/core/src/docs/rfcs/8188_compose_api.md +292 -0
  36. data/core/core/src/docs/rfcs/8194_compact_metadata_and_operation_args.md +444 -0
  37. data/core/core/src/docs/rfcs/README.md +14 -3
  38. data/core/core/src/docs/rfcs/mod.rs +46 -22
  39. data/core/core/src/docs/specs/README.md +34 -0
  40. data/core/core/src/docs/specs/conditional-operations.md +156 -0
  41. data/core/core/src/docs/specs/metadata.md +63 -0
  42. data/core/core/src/docs/specs/mod.rs +26 -0
  43. data/core/core/src/docs/upgrade.md +114 -1
  44. data/core/core/src/layers/capability_override.rs +15 -2
  45. data/core/core/src/layers/complete.rs +347 -43
  46. data/core/core/src/layers/correctness_check.rs +718 -51
  47. data/core/core/src/layers/error_context.rs +76 -2
  48. data/core/core/src/layers/simulate.rs +91 -28
  49. data/core/core/src/lib.rs +1 -0
  50. data/core/core/src/raw/accessor.rs +91 -15
  51. data/core/core/src/raw/enum_utils.rs +7 -0
  52. data/core/core/src/raw/http_util/header.rs +22 -17
  53. data/core/core/src/raw/oio/compose/api.rs +92 -0
  54. data/core/core/src/raw/oio/compose/mod.rs +19 -0
  55. data/core/core/src/raw/oio/copy/api.rs +3 -3
  56. data/core/core/src/raw/oio/copy/block_copy.rs +32 -4
  57. data/core/core/src/raw/oio/copy/multipart_copy.rs +36 -7
  58. data/core/core/src/raw/oio/entry.rs +48 -22
  59. data/core/core/src/raw/oio/list/flat_list.rs +1 -1
  60. data/core/core/src/raw/oio/list/hierarchy_list.rs +3 -2
  61. data/core/core/src/raw/oio/mod.rs +3 -0
  62. data/core/core/src/raw/oio/read/position_read.rs +1 -1
  63. data/core/core/src/raw/oio/write/api.rs +40 -0
  64. data/core/core/src/raw/oio/write/append_write.rs +4 -4
  65. data/core/core/src/raw/oio/write/block_write.rs +2 -2
  66. data/core/core/src/raw/oio/write/multipart_write.rs +181 -48
  67. data/core/core/src/raw/oio/write/position_write.rs +1 -1
  68. data/core/core/src/raw/operation.rs +6 -0
  69. data/core/core/src/raw/ops.rs +1191 -456
  70. data/core/core/src/raw/rps.rs +11 -0
  71. data/core/core/src/raw/time.rs +14 -3
  72. data/core/core/src/services/memory/backend.rs +5 -10
  73. data/core/core/src/services/memory/lister.rs +4 -4
  74. data/core/core/src/services/memory/writer.rs +7 -6
  75. data/core/core/src/types/buffer.rs +102 -12
  76. data/core/core/src/types/bytes_range.rs +20 -1
  77. data/core/core/src/types/capability.rs +65 -0
  78. data/core/core/src/types/compact.rs +329 -0
  79. data/core/core/src/types/compose/composer.rs +183 -0
  80. data/core/core/src/types/compose/input.rs +57 -0
  81. data/core/core/src/types/compose/mod.rs +23 -0
  82. data/core/core/src/types/context/read.rs +16 -11
  83. data/core/core/src/types/context/write.rs +150 -2
  84. data/core/core/src/types/copy.rs +5 -3
  85. data/core/core/src/types/delete/deleter.rs +20 -12
  86. data/core/core/src/types/delete/input.rs +22 -64
  87. data/core/core/src/types/delete/mod.rs +0 -1
  88. data/core/core/src/types/entry.rs +8 -14
  89. data/core/core/src/types/error.rs +28 -11
  90. data/core/core/src/types/metadata.rs +709 -322
  91. data/core/core/src/types/mod.rs +9 -1
  92. data/core/core/src/types/operator/operator.rs +278 -29
  93. data/core/core/src/types/operator/operator_futures.rs +466 -105
  94. data/core/core/src/types/options.rs +631 -158
  95. data/core/core/src/types/read/futures_async_reader.rs +663 -50
  96. data/core/core/src/types/read/reader.rs +23 -5
  97. data/core/core/src/types/write/futures_async_writer.rs +27 -0
  98. data/core/core/src/types/write/writer.rs +47 -5
  99. data/core/http-transports/reqwest/Cargo.toml +1 -1
  100. data/core/layers/async-backtrace/Cargo.toml +2 -2
  101. data/core/layers/async-backtrace/src/lib.rs +21 -2
  102. data/core/layers/await-tree/Cargo.toml +2 -2
  103. data/core/layers/await-tree/src/lib.rs +25 -2
  104. data/core/layers/capability-check/Cargo.toml +2 -2
  105. data/core/layers/capability-check/src/lib.rs +98 -10
  106. data/core/layers/chaos/Cargo.toml +2 -2
  107. data/core/layers/chaos/src/lib.rs +18 -3
  108. data/core/layers/concurrent-limit/Cargo.toml +3 -3
  109. data/core/layers/concurrent-limit/src/lib.rs +53 -13
  110. data/core/layers/dtrace/Cargo.toml +2 -2
  111. data/core/layers/dtrace/src/lib.rs +29 -2
  112. data/core/layers/fastmetrics/Cargo.toml +3 -3
  113. data/core/layers/fastrace/Cargo.toml +2 -2
  114. data/core/layers/fastrace/src/lib.rs +28 -2
  115. data/core/layers/foyer/Cargo.toml +2 -2
  116. data/core/layers/foyer/src/full.rs +16 -19
  117. data/core/layers/foyer/src/lib.rs +67 -14
  118. data/core/layers/hotpath/Cargo.toml +2 -2
  119. data/core/layers/hotpath/src/lib.rs +20 -2
  120. data/core/layers/immutable-index/Cargo.toml +2 -2
  121. data/core/layers/immutable-index/src/lib.rs +48 -24
  122. data/core/layers/logging/Cargo.toml +2 -2
  123. data/core/layers/logging/src/lib.rs +46 -2
  124. data/core/layers/metrics/Cargo.toml +3 -3
  125. data/core/layers/mime-guess/Cargo.toml +2 -2
  126. data/core/layers/mime-guess/src/lib.rs +31 -4
  127. data/core/layers/observe-metrics-common/Cargo.toml +2 -2
  128. data/core/layers/observe-metrics-common/src/lib.rs +55 -2
  129. data/core/layers/otelmetrics/Cargo.toml +3 -3
  130. data/core/layers/oteltrace/Cargo.toml +2 -2
  131. data/core/layers/oteltrace/src/lib.rs +27 -2
  132. data/core/layers/prometheus/Cargo.toml +3 -3
  133. data/core/layers/prometheus-client/Cargo.toml +3 -3
  134. data/core/layers/retry/Cargo.toml +4 -4
  135. data/core/layers/retry/src/lib.rs +76 -19
  136. data/core/layers/route/Cargo.toml +3 -3
  137. data/core/layers/route/src/lib.rs +34 -7
  138. data/core/layers/tail-cut/Cargo.toml +2 -2
  139. data/core/layers/tail-cut/src/lib.rs +28 -2
  140. data/core/layers/throttle/Cargo.toml +2 -2
  141. data/core/layers/throttle/src/lib.rs +19 -2
  142. data/core/layers/timeout/Cargo.toml +3 -3
  143. data/core/layers/timeout/src/lib.rs +38 -13
  144. data/core/layers/tracing/Cargo.toml +2 -2
  145. data/core/layers/tracing/src/lib.rs +24 -3
  146. data/core/services/aliyun-drive/Cargo.toml +2 -2
  147. data/core/services/aliyun-drive/src/backend.rs +34 -24
  148. data/core/services/aliyun-drive/src/core.rs +143 -54
  149. data/core/services/aliyun-drive/src/lister.rs +19 -18
  150. data/core/services/aliyun-drive/src/reader.rs +4 -1
  151. data/core/services/aliyun-drive/src/writer.rs +3 -3
  152. data/core/services/alluxio/Cargo.toml +1 -1
  153. data/core/services/alluxio/src/backend.rs +1 -1
  154. data/core/services/alluxio/src/core.rs +113 -94
  155. data/core/services/alluxio/src/reader.rs +7 -3
  156. data/core/services/alluxio/src/writer.rs +2 -2
  157. data/core/services/azblob/Cargo.toml +2 -2
  158. data/core/services/azblob/src/backend.rs +17 -9
  159. data/core/services/azblob/src/copier.rs +41 -15
  160. data/core/services/azblob/src/core.rs +372 -135
  161. data/core/services/azblob/src/deleter.rs +41 -18
  162. data/core/services/azblob/src/lister.rs +16 -10
  163. data/core/services/azblob/src/reader.rs +4 -1
  164. data/core/services/azblob/src/writer.rs +48 -15
  165. data/core/services/azdls/Cargo.toml +3 -3
  166. data/core/services/azdls/src/backend.rs +45 -15
  167. data/core/services/azdls/src/config.rs +4 -1
  168. data/core/services/azdls/src/core.rs +276 -87
  169. data/core/services/azdls/src/deleter.rs +13 -4
  170. data/core/services/azdls/src/lister.rs +18 -12
  171. data/core/services/azdls/src/reader.rs +6 -2
  172. data/core/services/azdls/src/writer.rs +44 -23
  173. data/core/services/azfile/Cargo.toml +2 -2
  174. data/core/services/azfile/src/backend.rs +24 -8
  175. data/core/services/azfile/src/core.rs +195 -77
  176. data/core/services/azfile/src/deleter.rs +8 -1
  177. data/core/services/azfile/src/lister.rs +20 -14
  178. data/core/services/azfile/src/reader.rs +5 -2
  179. data/core/services/azfile/src/writer.rs +27 -15
  180. data/core/services/azure-common/Cargo.toml +1 -1
  181. data/core/services/b2/Cargo.toml +2 -2
  182. data/core/services/b2/src/backend.rs +30 -11
  183. data/core/services/b2/src/core.rs +134 -120
  184. data/core/services/b2/src/deleter.rs +1 -1
  185. data/core/services/b2/src/lister.rs +5 -2
  186. data/core/services/b2/src/reader.rs +5 -2
  187. data/core/services/b2/src/writer.rs +29 -12
  188. data/core/services/cacache/Cargo.toml +1 -1
  189. data/core/services/cacache/src/backend.rs +4 -5
  190. data/core/services/cacache/src/reader.rs +4 -1
  191. data/core/services/cacache/src/writer.rs +6 -2
  192. data/core/services/cloudflare-kv/Cargo.toml +1 -1
  193. data/core/services/cloudflare-kv/src/backend.rs +26 -15
  194. data/core/services/cloudflare-kv/src/config.rs +13 -2
  195. data/core/services/cloudflare-kv/src/core.rs +62 -56
  196. data/core/services/cloudflare-kv/src/deleter.rs +12 -3
  197. data/core/services/cloudflare-kv/src/lister.rs +66 -17
  198. data/core/services/cloudflare-kv/src/reader.rs +14 -9
  199. data/core/services/cloudflare-kv/src/writer.rs +10 -7
  200. data/core/services/compfs/Cargo.toml +1 -1
  201. data/core/services/compfs/src/backend.rs +11 -7
  202. data/core/services/compfs/src/lister.rs +7 -7
  203. data/core/services/compfs/src/writer.rs +1 -1
  204. data/core/services/cos/Cargo.toml +1 -1
  205. data/core/services/cos/src/backend.rs +129 -16
  206. data/core/services/cos/src/core.rs +198 -80
  207. data/core/services/cos/src/deleter.rs +4 -1
  208. data/core/services/cos/src/lister.rs +42 -27
  209. data/core/services/cos/src/reader.rs +6 -2
  210. data/core/services/cos/src/writer.rs +45 -21
  211. data/core/services/d1/Cargo.toml +1 -1
  212. data/core/services/d1/src/backend.rs +6 -5
  213. data/core/services/d1/src/core.rs +79 -63
  214. data/core/services/d1/src/reader.rs +4 -1
  215. data/core/services/d1/src/writer.rs +6 -2
  216. data/core/services/dashmap/Cargo.toml +1 -1
  217. data/core/services/dashmap/src/backend.rs +2 -2
  218. data/core/services/dashmap/src/reader.rs +4 -1
  219. data/core/services/dashmap/src/writer.rs +11 -8
  220. data/core/services/dbfs/Cargo.toml +1 -1
  221. data/core/services/dbfs/src/backend.rs +21 -15
  222. data/core/services/dbfs/src/core.rs +65 -60
  223. data/core/services/dbfs/src/deleter.rs +4 -1
  224. data/core/services/dbfs/src/lister.rs +10 -10
  225. data/core/services/dbfs/src/writer.rs +6 -3
  226. data/core/services/dropbox/Cargo.toml +2 -2
  227. data/core/services/dropbox/src/backend.rs +30 -23
  228. data/core/services/dropbox/src/core.rs +65 -63
  229. data/core/services/dropbox/src/deleter.rs +1 -1
  230. data/core/services/dropbox/src/lister.rs +17 -8
  231. data/core/services/dropbox/src/reader.rs +4 -1
  232. data/core/services/dropbox/src/writer.rs +13 -10
  233. data/core/services/etcd/Cargo.toml +1 -1
  234. data/core/services/etcd/src/backend.rs +8 -5
  235. data/core/services/etcd/src/core.rs +5 -11
  236. data/core/services/etcd/src/lister.rs +6 -1
  237. data/core/services/etcd/src/reader.rs +4 -1
  238. data/core/services/etcd/src/writer.rs +6 -3
  239. data/core/services/foundationdb/Cargo.toml +1 -1
  240. data/core/services/foundationdb/src/backend.rs +6 -5
  241. data/core/services/foundationdb/src/reader.rs +4 -1
  242. data/core/services/foundationdb/src/writer.rs +6 -2
  243. data/core/services/foyer/Cargo.toml +3 -3
  244. data/core/services/foyer/src/backend.rs +6 -5
  245. data/core/services/foyer/src/reader.rs +4 -1
  246. data/core/services/foyer/src/writer.rs +6 -2
  247. data/core/services/fs/Cargo.toml +1 -1
  248. data/core/services/fs/src/backend.rs +4 -3
  249. data/core/services/fs/src/core.rs +44 -26
  250. data/core/services/fs/src/lister.rs +9 -6
  251. data/core/services/fs/src/writer.rs +20 -13
  252. data/core/services/ftp/Cargo.toml +4 -6
  253. data/core/services/ftp/src/backend.rs +9 -5
  254. data/core/services/ftp/src/core.rs +9 -7
  255. data/core/services/ftp/src/lister.rs +7 -8
  256. data/core/services/ftp/src/reader.rs +3 -3
  257. data/core/services/ftp/src/writer.rs +3 -3
  258. data/core/services/gcs/Cargo.toml +4 -2
  259. data/core/services/gcs/src/backend.rs +53 -7
  260. data/core/services/gcs/src/composer.rs +705 -0
  261. data/core/services/gcs/src/copier.rs +14 -4
  262. data/core/services/gcs/src/core.rs +828 -124
  263. data/core/services/gcs/src/deleter.rs +33 -18
  264. data/core/services/gcs/src/lib.rs +1 -0
  265. data/core/services/gcs/src/lister.rs +21 -12
  266. data/core/services/gcs/src/reader.rs +12 -5
  267. data/core/services/gcs/src/writer.rs +632 -10
  268. data/core/services/gcs-grpc/Cargo.toml +58 -0
  269. data/core/services/gcs-grpc/README.md +19 -0
  270. data/core/services/gcs-grpc/proto/README.md +23 -0
  271. data/core/services/gcs-grpc/proto/google/storage/v2/storage.proto +171 -0
  272. data/core/services/gcs-grpc/proto/upstream-descriptor.bin +0 -0
  273. data/core/services/gcs-grpc/src/backend.rs +449 -0
  274. data/core/services/gcs-grpc/src/config.rs +116 -0
  275. data/core/services/gcs-grpc/src/copier.rs +98 -0
  276. data/core/services/gcs-grpc/src/core.rs +298 -0
  277. data/core/services/gcs-grpc/src/deleter.rs +65 -0
  278. data/core/services/gcs-grpc/src/docs.md +19 -0
  279. data/core/services/gcs-grpc/src/generated/google.storage.v2.rs +541 -0
  280. data/core/services/gcs-grpc/src/generated/mod.rs +24 -0
  281. data/core/services/gcs-grpc/src/lib.rs +43 -0
  282. data/core/services/gcs-grpc/src/lister.rs +125 -0
  283. data/core/services/gcs-grpc/src/reader.rs +140 -0
  284. data/core/services/gcs-grpc/src/writer.rs +780 -0
  285. data/core/services/gdrive/Cargo.toml +2 -2
  286. data/core/services/gdrive/src/backend.rs +123 -69
  287. data/core/services/gdrive/src/core.rs +87 -69
  288. data/core/services/gdrive/src/deleter.rs +8 -2
  289. data/core/services/gdrive/src/lister.rs +38 -26
  290. data/core/services/gdrive/src/path_index.rs +2 -2
  291. data/core/services/gdrive/src/reader.rs +9 -3
  292. data/core/services/gdrive/src/writer.rs +13 -7
  293. data/core/services/ghac/Cargo.toml +2 -2
  294. data/core/services/ghac/src/backend.rs +5 -2
  295. data/core/services/ghac/src/core.rs +59 -37
  296. data/core/services/ghac/src/reader.rs +5 -2
  297. data/core/services/ghac/src/writer.rs +16 -6
  298. data/core/services/github/Cargo.toml +1 -1
  299. data/core/services/github/src/backend.rs +16 -8
  300. data/core/services/github/src/core.rs +88 -76
  301. data/core/services/github/src/lister.rs +17 -15
  302. data/core/services/github/src/reader.rs +5 -2
  303. data/core/services/github/src/writer.rs +12 -6
  304. data/core/services/goosefs/Cargo.toml +2 -2
  305. data/core/services/goosefs/src/backend.rs +2 -2
  306. data/core/services/goosefs/src/core.rs +291 -208
  307. data/core/services/goosefs/src/docs.md +3 -0
  308. data/core/services/goosefs/src/lister.rs +2 -3
  309. data/core/services/goosefs/src/reader.rs +7 -3
  310. data/core/services/goosefs/src/writer.rs +21 -10
  311. data/core/services/goosefs/tests/safe_conditional_put.rs +37 -0
  312. data/core/services/gridfs/Cargo.toml +2 -2
  313. data/core/services/gridfs/src/backend.rs +12 -8
  314. data/core/services/gridfs/src/core.rs +1 -1
  315. data/core/services/gridfs/src/reader.rs +4 -1
  316. data/core/services/gridfs/src/writer.rs +6 -2
  317. data/core/services/hdfs/Cargo.toml +1 -1
  318. data/core/services/hdfs/src/backend.rs +1 -1
  319. data/core/services/hdfs/src/core.rs +7 -4
  320. data/core/services/hdfs/src/lister.rs +7 -9
  321. data/core/services/hdfs/src/writer.rs +5 -1
  322. data/core/services/hdfs-native/Cargo.toml +1 -1
  323. data/core/services/hdfs-native/src/backend.rs +1 -1
  324. data/core/services/hdfs-native/src/core.rs +44 -50
  325. data/core/services/hdfs-native/src/lister.rs +8 -10
  326. data/core/services/hdfs-native/src/writer.rs +5 -1
  327. data/core/services/hf/Cargo.toml +4 -3
  328. data/core/services/hf/src/backend.rs +4 -3
  329. data/core/services/hf/src/core.rs +907 -153
  330. data/core/services/hf/src/lister.rs +16 -6
  331. data/core/services/hf/src/reader.rs +377 -57
  332. data/core/services/hf/src/writer.rs +6 -2
  333. data/core/services/http/Cargo.toml +3 -3
  334. data/core/services/http/src/backend.rs +8 -6
  335. data/core/services/http/src/core.rs +57 -35
  336. data/core/services/http/src/reader.rs +5 -2
  337. data/core/services/ipfs/Cargo.toml +1 -1
  338. data/core/services/ipfs/src/backend.rs +20 -9
  339. data/core/services/ipfs/src/core.rs +43 -34
  340. data/core/services/ipfs/src/reader.rs +5 -2
  341. data/core/services/ipmfs/Cargo.toml +1 -1
  342. data/core/services/ipmfs/src/backend.rs +17 -8
  343. data/core/services/ipmfs/src/core.rs +66 -60
  344. data/core/services/ipmfs/src/deleter.rs +5 -2
  345. data/core/services/ipmfs/src/lister.rs +15 -12
  346. data/core/services/ipmfs/src/reader.rs +5 -2
  347. data/core/services/ipmfs/src/writer.rs +6 -3
  348. data/core/services/koofr/Cargo.toml +2 -2
  349. data/core/services/koofr/src/backend.rs +46 -17
  350. data/core/services/koofr/src/core.rs +64 -48
  351. data/core/services/koofr/src/deleter.rs +4 -1
  352. data/core/services/koofr/src/lister.rs +11 -10
  353. data/core/services/koofr/src/reader.rs +5 -2
  354. data/core/services/koofr/src/writer.rs +13 -7
  355. data/core/services/lakefs/Cargo.toml +1 -1
  356. data/core/services/lakefs/src/backend.rs +25 -8
  357. data/core/services/lakefs/src/core.rs +79 -73
  358. data/core/services/lakefs/src/deleter.rs +4 -1
  359. data/core/services/lakefs/src/lister.rs +17 -14
  360. data/core/services/lakefs/src/reader.rs +5 -2
  361. data/core/services/lakefs/src/writer.rs +11 -10
  362. data/core/services/memcached/Cargo.toml +1 -1
  363. data/core/services/memcached/src/backend.rs +57 -7
  364. data/core/services/memcached/src/config.rs +13 -2
  365. data/core/services/memcached/src/core.rs +11 -1
  366. data/core/services/memcached/src/reader.rs +4 -1
  367. data/core/services/memcached/src/writer.rs +6 -2
  368. data/core/services/mini_moka/Cargo.toml +1 -1
  369. data/core/services/mini_moka/src/backend.rs +8 -8
  370. data/core/services/mini_moka/src/reader.rs +4 -1
  371. data/core/services/mini_moka/src/writer.rs +11 -7
  372. data/core/services/moka/Cargo.toml +1 -1
  373. data/core/services/moka/src/backend.rs +7 -7
  374. data/core/services/moka/src/reader.rs +4 -1
  375. data/core/services/moka/src/writer.rs +10 -6
  376. data/core/services/mongodb/Cargo.toml +2 -2
  377. data/core/services/mongodb/src/backend.rs +7 -6
  378. data/core/services/mongodb/src/core.rs +1 -1
  379. data/core/services/mongodb/src/reader.rs +4 -1
  380. data/core/services/mongodb/src/writer.rs +6 -2
  381. data/core/services/monoiofs/Cargo.toml +2 -2
  382. data/core/services/monoiofs/src/backend.rs +16 -10
  383. data/core/services/monoiofs/src/core.rs +8 -9
  384. data/core/services/monoiofs/src/reader.rs +8 -10
  385. data/core/services/monoiofs/src/writer.rs +19 -24
  386. data/core/services/mysql/Cargo.toml +2 -2
  387. data/core/services/mysql/src/backend.rs +7 -6
  388. data/core/services/mysql/src/core.rs +1 -1
  389. data/core/services/mysql/src/lister.rs +7 -3
  390. data/core/services/mysql/src/reader.rs +4 -1
  391. data/core/services/mysql/src/writer.rs +6 -2
  392. data/core/services/obs/Cargo.toml +1 -1
  393. data/core/services/obs/src/backend.rs +29 -11
  394. data/core/services/obs/src/core.rs +81 -82
  395. data/core/services/obs/src/deleter.rs +4 -1
  396. data/core/services/obs/src/lister.rs +12 -5
  397. data/core/services/obs/src/reader.rs +5 -2
  398. data/core/services/obs/src/writer.rs +40 -19
  399. data/core/services/onedrive/Cargo.toml +2 -2
  400. data/core/services/onedrive/src/backend.rs +30 -21
  401. data/core/services/onedrive/src/config.rs +2 -2
  402. data/core/services/onedrive/src/core.rs +191 -90
  403. data/core/services/onedrive/src/deleter.rs +5 -2
  404. data/core/services/onedrive/src/graph_model.rs +10 -51
  405. data/core/services/onedrive/src/lister.rs +60 -24
  406. data/core/services/onedrive/src/reader.rs +17 -2
  407. data/core/services/onedrive/src/writer.rs +26 -15
  408. data/core/services/opfs/Cargo.toml +1 -1
  409. data/core/services/opfs/src/backend.rs +6 -13
  410. data/core/services/opfs/src/core.rs +33 -37
  411. data/core/services/opfs/src/lister.rs +4 -4
  412. data/core/services/opfs/src/writer.rs +1 -3
  413. data/core/services/oss/Cargo.toml +1 -1
  414. data/core/services/oss/src/backend.rs +40 -8
  415. data/core/services/oss/src/core.rs +192 -92
  416. data/core/services/oss/src/deleter.rs +16 -6
  417. data/core/services/oss/src/lister.rs +43 -27
  418. data/core/services/oss/src/reader.rs +6 -2
  419. data/core/services/oss/src/writer.rs +40 -22
  420. data/core/services/pcloud/Cargo.toml +1 -1
  421. data/core/services/pcloud/src/backend.rs +40 -6
  422. data/core/services/pcloud/src/core.rs +80 -66
  423. data/core/services/pcloud/src/deleter.rs +8 -1
  424. data/core/services/pcloud/src/lister.rs +4 -1
  425. data/core/services/pcloud/src/reader.rs +5 -2
  426. data/core/services/pcloud/src/writer.rs +6 -3
  427. data/core/services/persy/Cargo.toml +1 -1
  428. data/core/services/persy/src/backend.rs +6 -5
  429. data/core/services/persy/src/core.rs +60 -15
  430. data/core/services/persy/src/reader.rs +4 -1
  431. data/core/services/persy/src/writer.rs +6 -2
  432. data/core/services/postgresql/Cargo.toml +2 -2
  433. data/core/services/postgresql/src/backend.rs +7 -6
  434. data/core/services/postgresql/src/core.rs +1 -1
  435. data/core/services/postgresql/src/reader.rs +4 -1
  436. data/core/services/postgresql/src/writer.rs +6 -2
  437. data/core/services/redb/Cargo.toml +1 -1
  438. data/core/services/redb/src/backend.rs +6 -5
  439. data/core/services/redb/src/reader.rs +4 -1
  440. data/core/services/redb/src/writer.rs +6 -2
  441. data/core/services/redis/Cargo.toml +1 -1
  442. data/core/services/redis/src/backend.rs +18 -8
  443. data/core/services/redis/src/config.rs +13 -2
  444. data/core/services/redis/src/reader.rs +8 -4
  445. data/core/services/redis/src/writer.rs +6 -2
  446. data/core/services/rocksdb/Cargo.toml +1 -1
  447. data/core/services/rocksdb/src/backend.rs +6 -5
  448. data/core/services/rocksdb/src/lister.rs +6 -5
  449. data/core/services/rocksdb/src/reader.rs +4 -1
  450. data/core/services/rocksdb/src/writer.rs +6 -2
  451. data/core/services/s3/Cargo.toml +5 -4
  452. data/core/services/s3/src/backend.rs +995 -39
  453. data/core/services/s3/src/compatible_services.md +57 -0
  454. data/core/services/s3/src/config.rs +16 -0
  455. data/core/services/s3/src/copier.rs +190 -55
  456. data/core/services/s3/src/core.rs +299 -190
  457. data/core/services/s3/src/deleter.rs +26 -7
  458. data/core/services/s3/src/docs.md +57 -0
  459. data/core/services/s3/src/lister.rs +55 -36
  460. data/core/services/s3/src/reader.rs +22 -2
  461. data/core/services/s3/src/writer.rs +154 -32
  462. data/core/services/seafile/Cargo.toml +2 -2
  463. data/core/services/seafile/src/backend.rs +3 -3
  464. data/core/services/seafile/src/core.rs +105 -79
  465. data/core/services/seafile/src/lister.rs +11 -8
  466. data/core/services/seafile/src/reader.rs +5 -2
  467. data/core/services/seafile/src/writer.rs +6 -3
  468. data/core/services/sftp/Cargo.toml +1 -1
  469. data/core/services/sftp/src/backend.rs +19 -4
  470. data/core/services/sftp/src/core.rs +51 -46
  471. data/core/services/sftp/src/lister.rs +4 -4
  472. data/core/services/sftp/src/writer.rs +1 -1
  473. data/core/services/sled/Cargo.toml +1 -1
  474. data/core/services/sled/src/backend.rs +6 -5
  475. data/core/services/sled/src/core.rs +28 -6
  476. data/core/services/sled/src/lister.rs +6 -5
  477. data/core/services/sled/src/reader.rs +4 -1
  478. data/core/services/sled/src/writer.rs +6 -2
  479. data/core/services/sqlite/Cargo.toml +2 -2
  480. data/core/services/sqlite/src/backend.rs +12 -7
  481. data/core/services/sqlite/src/core.rs +3 -3
  482. data/core/services/sqlite/src/reader.rs +4 -1
  483. data/core/services/sqlite/src/writer.rs +7 -3
  484. data/core/services/surrealdb/Cargo.toml +2 -2
  485. data/core/services/surrealdb/src/backend.rs +7 -6
  486. data/core/services/surrealdb/src/core.rs +1 -1
  487. data/core/services/surrealdb/src/reader.rs +4 -1
  488. data/core/services/surrealdb/src/writer.rs +6 -2
  489. data/core/services/swift/Cargo.toml +1 -1
  490. data/core/services/swift/src/backend.rs +38 -8
  491. data/core/services/swift/src/core.rs +63 -67
  492. data/core/services/swift/src/deleter.rs +8 -2
  493. data/core/services/swift/src/lister.rs +11 -8
  494. data/core/services/swift/src/reader.rs +5 -2
  495. data/core/services/swift/src/writer.rs +17 -8
  496. data/core/services/tikv/Cargo.toml +2 -2
  497. data/core/services/tikv/src/backend.rs +7 -6
  498. data/core/services/tikv/src/core.rs +31 -14
  499. data/core/services/tikv/src/reader.rs +4 -1
  500. data/core/services/tikv/src/writer.rs +6 -2
  501. data/core/services/tos/Cargo.toml +2 -2
  502. data/core/services/tos/src/backend.rs +45 -21
  503. data/core/services/tos/src/copier.rs +44 -17
  504. data/core/services/tos/src/core.rs +147 -117
  505. data/core/services/tos/src/deleter.rs +9 -3
  506. data/core/services/tos/src/docs.md +1 -1
  507. data/core/services/tos/src/lister.rs +43 -28
  508. data/core/services/tos/src/reader.rs +5 -2
  509. data/core/services/tos/src/writer.rs +37 -16
  510. data/core/services/upyun/Cargo.toml +1 -1
  511. data/core/services/upyun/src/backend.rs +30 -7
  512. data/core/services/upyun/src/core.rs +122 -87
  513. data/core/services/upyun/src/deleter.rs +4 -1
  514. data/core/services/upyun/src/lister.rs +10 -10
  515. data/core/services/upyun/src/reader.rs +5 -2
  516. data/core/services/upyun/src/writer.rs +19 -7
  517. data/core/services/vercel-artifacts/Cargo.toml +1 -1
  518. data/core/services/vercel-artifacts/src/backend.rs +6 -3
  519. data/core/services/vercel-artifacts/src/core.rs +32 -27
  520. data/core/services/vercel-artifacts/src/reader.rs +5 -2
  521. data/core/services/vercel-artifacts/src/writer.rs +6 -3
  522. data/core/services/vercel-blob/Cargo.toml +1 -1
  523. data/core/services/vercel-blob/src/backend.rs +23 -6
  524. data/core/services/vercel-blob/src/core.rs +92 -81
  525. data/core/services/vercel-blob/src/lister.rs +12 -3
  526. data/core/services/vercel-blob/src/reader.rs +5 -2
  527. data/core/services/vercel-blob/src/writer.rs +19 -7
  528. data/core/services/webdav/Cargo.toml +2 -2
  529. data/core/services/webdav/src/backend.rs +25 -5
  530. data/core/services/webdav/src/core.rs +116 -59
  531. data/core/services/webdav/src/deleter.rs +4 -1
  532. data/core/services/webdav/src/lister.rs +4 -1
  533. data/core/services/webdav/src/reader.rs +6 -2
  534. data/core/services/webdav/src/writer.rs +17 -7
  535. data/core/services/webhdfs/Cargo.toml +2 -2
  536. data/core/services/webhdfs/src/backend.rs +24 -11
  537. data/core/services/webhdfs/src/core.rs +99 -98
  538. data/core/services/webhdfs/src/deleter.rs +5 -2
  539. data/core/services/webhdfs/src/lister.rs +21 -9
  540. data/core/services/webhdfs/src/reader.rs +5 -2
  541. data/core/services/webhdfs/src/writer.rs +49 -14
  542. data/core/services/yandex-disk/Cargo.toml +1 -1
  543. data/core/services/yandex-disk/src/backend.rs +28 -6
  544. data/core/services/yandex-disk/src/core.rs +97 -79
  545. data/core/services/yandex-disk/src/deleter.rs +4 -1
  546. data/core/services/yandex-disk/src/lister.rs +25 -9
  547. data/core/services/yandex-disk/src/reader.rs +5 -2
  548. data/core/services/yandex-disk/src/writer.rs +6 -3
  549. data/core/src/lib.rs +5 -0
  550. data/core/testkit/Cargo.toml +4 -4
  551. data/core/testkit/src/utils.rs +53 -8
  552. data/core/tests/behavior/async_compose.rs +297 -0
  553. data/core/tests/behavior/async_copy.rs +162 -1
  554. data/core/tests/behavior/async_delete.rs +364 -3
  555. data/core/tests/behavior/async_read.rs +86 -0
  556. data/core/tests/behavior/async_restore.rs +162 -0
  557. data/core/tests/behavior/async_stat.rs +90 -0
  558. data/core/tests/behavior/async_write.rs +330 -2
  559. data/core/tests/behavior/main.rs +4 -0
  560. data/core/upgrade.md +114 -1
  561. data/src/capability.rs +0 -1
  562. data/src/io.rs +0 -1
  563. data/src/lister.rs +0 -1
  564. data/src/metadata.rs +0 -1
  565. data/src/operator_info.rs +0 -1
  566. metadata +44 -2
@@ -298,6 +298,7 @@ impl<I: RetryInterceptor> Service for RetryService<I> {
298
298
  type Lister = RetryWrapper<oio::Lister, I>;
299
299
  type Deleter = RetryWrapper<oio::Deleter, I>;
300
300
  type Copier = RetryWrapper<oio::Copier, I>;
301
+ type Composer = oio::Composer;
301
302
 
302
303
  fn info(&self) -> ServiceInfo {
303
304
  self.inner.info()
@@ -307,6 +308,10 @@ impl<I: RetryInterceptor> Service for RetryService<I> {
307
308
  self.inner.capability()
308
309
  }
309
310
 
311
+ fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
312
+ self.inner.compose(ctx, to, args)
313
+ }
314
+
310
315
  async fn create_dir(
311
316
  &self,
312
317
  ctx: &OperationContext,
@@ -418,10 +423,9 @@ impl<I: RetryInterceptor> Service for RetryService<I> {
418
423
  from: &str,
419
424
  to: &str,
420
425
  args: OpCopy,
421
- opts: OpCopier,
422
426
  ) -> Result<Self::Copier> {
423
427
  let mut attempt: u32 = 0;
424
- let copier = { || self.inner.copy(ctx, from, to, args.clone(), opts.clone()) }
428
+ let copier = { || self.inner.copy(ctx, from, to, args.clone()) }
425
429
  .retry(self.builder)
426
430
  .when(|e| e.is_temporary())
427
431
  .notify(|err, dur| {
@@ -463,6 +467,29 @@ impl<I: RetryInterceptor> Service for RetryService<I> {
463
467
  .map_err(|err| err.set_persistent())
464
468
  }
465
469
 
470
+ async fn restore(
471
+ &self,
472
+ ctx: &OperationContext,
473
+ path: &str,
474
+ args: OpRestore,
475
+ ) -> Result<RpRestore> {
476
+ let mut attempt: u32 = 0;
477
+ { || self.inner.restore(ctx, path, args.clone()) }
478
+ .retry(self.builder)
479
+ .when(|e| e.is_temporary())
480
+ .notify(|err, dur| {
481
+ attempt += 1;
482
+ self.notify.intercept(RetryEvent {
483
+ op: Operation::Restore,
484
+ err,
485
+ retry_after: dur,
486
+ attempt,
487
+ })
488
+ })
489
+ .await
490
+ .map_err(|err| err.set_persistent())
491
+ }
492
+
466
493
  fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
467
494
  let mut attempt: u32 = 0;
468
495
  let lister = { || self.inner.list(ctx, path, args.clone()) }
@@ -765,6 +792,38 @@ impl<R: oio::Write, I: RetryInterceptor> oio::Write for RetryWrapper<R, I> {
765
792
  res.map_err(|err| err.set_persistent())
766
793
  }
767
794
 
795
+ async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
796
+ use backon::RetryableWithContext;
797
+
798
+ let inner = self.take_inner()?;
799
+ let path = path.to_string();
800
+ let mut attempt: u32 = 0;
801
+
802
+ let ((inner, _, _, _), res) = {
803
+ |(mut r, path, args, range): (R, String, OpRead, BytesRange)| async move {
804
+ let res = r.copy_from(&path, args.clone(), range).await;
805
+
806
+ ((r, path, args, range), res)
807
+ }
808
+ }
809
+ .retry(self.builder)
810
+ .when(|e| e.is_temporary())
811
+ .context((inner, path, args, range))
812
+ .notify(|err, dur| {
813
+ attempt += 1;
814
+ self.notify.intercept(RetryEvent {
815
+ op: Operation::Write,
816
+ err,
817
+ retry_after: dur,
818
+ attempt,
819
+ })
820
+ })
821
+ .await;
822
+
823
+ self.inner = Some(inner);
824
+ res.map_err(|err| err.set_persistent())
825
+ }
826
+
768
827
  async fn abort(&mut self) -> Result<()> {
769
828
  use backon::RetryableWithContext;
770
829
 
@@ -1073,7 +1132,10 @@ mod tests {
1073
1132
  impl oio::StreamRead for MockReader {
1074
1133
  async fn open(&self, range: BytesRange) -> Result<(RpRead, Box<dyn oio::ReadStreamDyn>)> {
1075
1134
  let backend = &self.backend;
1076
- let rp = RpRead::new(Metadata::new(EntryMode::FILE).with_content_length(0));
1135
+ let rp = RpRead::new({
1136
+ let metadata = MetadataBuilder::file(13);
1137
+ metadata.build()
1138
+ });
1077
1139
  let stream = MockReadStream {
1078
1140
  buf: Bytes::from("Hello, World!").into(),
1079
1141
  range,
@@ -1090,6 +1152,7 @@ mod tests {
1090
1152
  type Lister = MockLister;
1091
1153
  type Deleter = MockDeleter;
1092
1154
  type Copier = MockCopier;
1155
+ type Composer = ();
1093
1156
 
1094
1157
  fn info(&self) -> ServiceInfo {
1095
1158
  ServiceInfo::with_scheme("mock")
@@ -1123,9 +1186,10 @@ mod tests {
1123
1186
  }
1124
1187
 
1125
1188
  async fn stat(&self, _: &OperationContext, _: &str, _: OpStat) -> Result<RpStat> {
1126
- Ok(RpStat::new(
1127
- Metadata::new(EntryMode::FILE).with_content_length(13),
1128
- ))
1189
+ Ok(RpStat::new({
1190
+ let metadata = MetadataBuilder::file(13);
1191
+ metadata.build()
1192
+ }))
1129
1193
  }
1130
1194
 
1131
1195
  fn read(&self, _: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
@@ -1152,14 +1216,7 @@ mod tests {
1152
1216
  Ok(lister)
1153
1217
  }
1154
1218
 
1155
- fn copy(
1156
- &self,
1157
- _: &OperationContext,
1158
- _: &str,
1159
- _: &str,
1160
- _: OpCopy,
1161
- _: OpCopier,
1162
- ) -> Result<Self::Copier> {
1219
+ fn copy(&self, _: &OperationContext, _: &str, _: &str, _: OpCopy) -> Result<Self::Copier> {
1163
1220
  Ok(MockCopier {
1164
1221
  attempt: self.attempt.clone(),
1165
1222
  })
@@ -1253,11 +1310,11 @@ mod tests {
1253
1310
  .set_temporary()),
1254
1311
  2 => Ok(Some(oio::Entry::new(
1255
1312
  "hello",
1256
- Metadata::new(EntryMode::FILE),
1313
+ MetadataBuilder::file(0).build(),
1257
1314
  ))),
1258
1315
  3 => Ok(Some(oio::Entry::new(
1259
1316
  "world",
1260
- Metadata::new(EntryMode::FILE),
1317
+ MetadataBuilder::file(0).build(),
1261
1318
  ))),
1262
1319
  4 => Err(
1263
1320
  Error::new(ErrorKind::Unexpected, "retryable internal server error")
@@ -1265,11 +1322,11 @@ mod tests {
1265
1322
  ),
1266
1323
  5 => Ok(Some(oio::Entry::new(
1267
1324
  "2023/",
1268
- Metadata::new(EntryMode::DIR),
1325
+ MetadataBuilder::dir().build(),
1269
1326
  ))),
1270
1327
  6 => Ok(Some(oio::Entry::new(
1271
1328
  "0208/",
1272
- Metadata::new(EntryMode::DIR),
1329
+ MetadataBuilder::dir().build(),
1273
1330
  ))),
1274
1331
  7 => Ok(None),
1275
1332
  _ => {
@@ -1354,7 +1411,7 @@ mod tests {
1354
1411
  }
1355
1412
 
1356
1413
  async fn close(&mut self) -> Result<Metadata> {
1357
- Ok(Metadata::default())
1414
+ Ok(MetadataBuilder::unknown().build())
1358
1415
  }
1359
1416
 
1360
1417
  async fn abort(&mut self) -> Result<()> {
@@ -33,10 +33,10 @@ all-features = true
33
33
 
34
34
  [dependencies]
35
35
  globset = "0.4.15"
36
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
36
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
37
37
 
38
38
  [dev-dependencies]
39
39
  futures = { workspace = true }
40
- opendal-core = { path = "../../core", version = "0.58.1" }
41
- opendal-service-fs = { path = "../../services/fs", version = "0.58.1" }
40
+ opendal-core = { path = "../../core", version = "0.59.0" }
41
+ opendal-service-fs = { path = "../../services/fs", version = "0.59.0" }
42
42
  tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
@@ -196,13 +196,29 @@ impl Service for RouteAccessor {
196
196
  type Lister = oio::Lister;
197
197
  type Deleter = oio::Deleter;
198
198
  type Copier = oio::Copier;
199
+ type Composer = ();
199
200
 
200
201
  fn info(&self) -> ServiceInfo {
201
202
  self.inner.info()
202
203
  }
203
204
 
204
205
  fn capability(&self) -> Capability {
205
- self.inner.capability()
206
+ let mut capability = self.inner.capability();
207
+ capability.write_can_copy_from = false;
208
+ capability.compose = false;
209
+ capability.compose_with_content_type = false;
210
+ capability.compose_with_content_disposition = false;
211
+ capability.compose_with_content_encoding = false;
212
+ capability.compose_with_cache_control = false;
213
+ capability.compose_with_user_metadata = false;
214
+ capability.compose_with_if_match = false;
215
+ capability.compose_with_if_none_match = false;
216
+ capability.compose_with_if_version_match = false;
217
+ capability.compose_with_if_version_not_match = false;
218
+ capability.compose_with_if_not_exists = false;
219
+ capability.compose_with_source_version = false;
220
+ capability.compose_with_source_if_match = false;
221
+ capability
206
222
  }
207
223
 
208
224
  async fn create_dir(
@@ -237,11 +253,10 @@ impl Service for RouteAccessor {
237
253
  from: &str,
238
254
  to: &str,
239
255
  args: OpCopy,
240
- opts: OpCopier,
241
256
  ) -> Result<oio::Copier> {
242
257
  match self.select(from) {
243
- RouteSelected::Default(srv) => srv.copy(ctx, from, to, args, opts),
244
- RouteSelected::Target(target) => target.srv.copy(&target.ctx, from, to, args, opts),
258
+ RouteSelected::Default(srv) => srv.copy(ctx, from, to, args),
259
+ RouteSelected::Target(target) => target.srv.copy(&target.ctx, from, to, args),
245
260
  }
246
261
  }
247
262
 
@@ -258,6 +273,18 @@ impl Service for RouteAccessor {
258
273
  }
259
274
  }
260
275
 
276
+ async fn restore(
277
+ &self,
278
+ ctx: &OperationContext,
279
+ path: &str,
280
+ args: OpRestore,
281
+ ) -> Result<RpRestore> {
282
+ match self.select(path) {
283
+ RouteSelected::Default(srv) => srv.restore(ctx, path, args).await,
284
+ RouteSelected::Target(target) => target.srv.restore(&target.ctx, path, args).await,
285
+ }
286
+ }
287
+
261
288
  async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
262
289
  match self.select(path) {
263
290
  RouteSelected::Default(srv) => srv.stat(ctx, path, args).await,
@@ -467,6 +494,7 @@ mod tests {
467
494
  type Lister = ();
468
495
  type Deleter = ();
469
496
  type Copier = ();
497
+ type Composer = ();
470
498
 
471
499
  fn info(&self) -> ServiceInfo {
472
500
  self.info.clone()
@@ -496,7 +524,7 @@ mod tests {
496
524
 
497
525
  async fn stat(&self, _: &OperationContext, path: &str, _: OpStat) -> Result<RpStat> {
498
526
  if self.paths.lock().unwrap().contains(path) {
499
- Ok(RpStat::new(Metadata::new(EntryMode::FILE)))
527
+ Ok(RpStat::new(MetadataBuilder::file(0).build()))
500
528
  } else {
501
529
  Err(Error::new(ErrorKind::NotFound, "path not found"))
502
530
  }
@@ -536,7 +564,6 @@ mod tests {
536
564
  from: &str,
537
565
  to: &str,
538
566
  _: OpCopy,
539
- _: OpCopier,
540
567
  ) -> Result<Self::Copier> {
541
568
  if !self.paths.lock().unwrap().contains(from) {
542
569
  return Err(Error::new(ErrorKind::NotFound, "source not found"));
@@ -580,7 +607,7 @@ mod tests {
580
607
 
581
608
  async fn close(&mut self) -> Result<Metadata> {
582
609
  self.paths.lock().unwrap().insert(self.path.clone());
583
- Ok(Metadata::new(EntryMode::FILE))
610
+ Ok(MetadataBuilder::unknown().build())
584
611
  }
585
612
 
586
613
  async fn abort(&mut self) -> Result<()> {
@@ -32,9 +32,9 @@ version = { workspace = true }
32
32
  all-features = true
33
33
 
34
34
  [dependencies]
35
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
35
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
36
36
  tokio = { workspace = true, features = ["time"] }
37
37
 
38
38
  [dev-dependencies]
39
- opendal-core = { path = "../../core", version = "0.58.1" }
39
+ opendal-core = { path = "../../core", version = "0.59.0" }
40
40
  tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
@@ -371,6 +371,7 @@ impl Service for TailCutService {
371
371
  type Lister = TailCutWrapper<oio::Lister>;
372
372
  type Deleter = TailCutWrapper<oio::Deleter>;
373
373
  type Copier = TailCutWrapper<oio::Copier>;
374
+ type Composer = oio::Composer;
374
375
 
375
376
  fn info(&self) -> ServiceInfo {
376
377
  self.inner.info()
@@ -380,6 +381,10 @@ impl Service for TailCutService {
380
381
  self.inner.capability()
381
382
  }
382
383
 
384
+ fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
385
+ self.inner.compose(ctx, to, args)
386
+ }
387
+
383
388
  async fn create_dir(
384
389
  &self,
385
390
  ctx: &OperationContext,
@@ -412,10 +417,9 @@ impl Service for TailCutService {
412
417
  from: &str,
413
418
  to: &str,
414
419
  args: OpCopy,
415
- opts: OpCopier,
416
420
  ) -> Result<Self::Copier> {
417
421
  self.inner
418
- .copy(ctx, from, to, args, opts)
422
+ .copy(ctx, from, to, args)
419
423
  .map(|c| TailCutWrapper::new(c, None, self.config.clone(), self.stats.clone()))
420
424
  }
421
425
 
@@ -434,6 +438,15 @@ impl Service for TailCutService {
434
438
  .await
435
439
  }
436
440
 
441
+ async fn restore(
442
+ &self,
443
+ ctx: &OperationContext,
444
+ path: &str,
445
+ args: OpRestore,
446
+ ) -> Result<RpRestore> {
447
+ self.inner.restore(ctx, path, args).await
448
+ }
449
+
437
450
  async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
438
451
  self.with_deadline(Operation::Stat, None, self.inner.stat(ctx, path, args))
439
452
  .await
@@ -615,6 +628,19 @@ impl<R: oio::Write> oio::Write for TailCutWrapper<R> {
615
628
  .await
616
629
  }
617
630
 
631
+ async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
632
+ let deadline = self.calculate_deadline(Operation::Write);
633
+ Self::with_io_deadline(
634
+ deadline,
635
+ self.config.percentile,
636
+ &self.stats,
637
+ self.size,
638
+ Operation::Write,
639
+ self.inner.copy_from(path, args, range),
640
+ )
641
+ .await
642
+ }
643
+
618
644
  async fn close(&mut self) -> Result<Metadata> {
619
645
  let deadline = self.calculate_deadline(Operation::Write);
620
646
  Self::with_io_deadline(
@@ -33,7 +33,7 @@ all-features = true
33
33
 
34
34
  [dependencies]
35
35
  governor = "0.10.4"
36
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
36
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
37
37
 
38
38
  [dev-dependencies]
39
- opendal-core = { path = "../../core", version = "0.58.1" }
39
+ opendal-core = { path = "../../core", version = "0.59.0" }
@@ -118,6 +118,7 @@ impl Service for ThrottleAccessor {
118
118
  type Lister = oio::Lister;
119
119
  type Deleter = oio::Deleter;
120
120
  type Copier = oio::Copier;
121
+ type Composer = oio::Composer;
121
122
 
122
123
  fn info(&self) -> ServiceInfo {
123
124
  self.inner.info()
@@ -127,6 +128,10 @@ impl Service for ThrottleAccessor {
127
128
  self.inner.capability()
128
129
  }
129
130
 
131
+ fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
132
+ self.inner.compose(ctx, to, args)
133
+ }
134
+
130
135
  async fn create_dir(
131
136
  &self,
132
137
  ctx: &OperationContext,
@@ -162,9 +167,8 @@ impl Service for ThrottleAccessor {
162
167
  from: &str,
163
168
  to: &str,
164
169
  args: OpCopy,
165
- opts: OpCopier,
166
170
  ) -> Result<Self::Copier> {
167
- self.inner.copy(ctx, from, to, args, opts)
171
+ self.inner.copy(ctx, from, to, args)
168
172
  }
169
173
 
170
174
  fn delete(&self, ctx: &OperationContext) -> Result<Self::Deleter> {
@@ -181,6 +185,15 @@ impl Service for ThrottleAccessor {
181
185
  self.inner.rename(ctx, from, to, args).await
182
186
  }
183
187
 
188
+ async fn restore(
189
+ &self,
190
+ ctx: &OperationContext,
191
+ path: &str,
192
+ args: OpRestore,
193
+ ) -> Result<RpRestore> {
194
+ self.inner.restore(ctx, path, args).await
195
+ }
196
+
184
197
  fn list(&self, ctx: &OperationContext, path: &str, args: OpList) -> Result<Self::Lister> {
185
198
  self.inner.list(ctx, path, args)
186
199
  }
@@ -258,6 +271,10 @@ impl<R: oio::Write> oio::Write for ThrottleWrapper<R> {
258
271
  self.inner.write(bs).await
259
272
  }
260
273
 
274
+ async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
275
+ self.inner.copy_from(path, args, range).await
276
+ }
277
+
261
278
  async fn close(&mut self) -> Result<Metadata> {
262
279
  self.inner.close().await
263
280
  }
@@ -32,11 +32,11 @@ version = { workspace = true }
32
32
  all-features = true
33
33
 
34
34
  [dependencies]
35
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
35
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
36
36
  tokio = { workspace = true, features = ["time"] }
37
37
 
38
38
  [dev-dependencies]
39
39
  futures = { workspace = true }
40
- opendal-core = { path = "../../core", version = "0.58.1" }
41
- opendal-layer-retry = { path = "../retry", version = "0.58.1" }
40
+ opendal-core = { path = "../../core", version = "0.59.0" }
41
+ opendal-layer-retry = { path = "../retry", version = "0.59.0" }
42
42
  tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
@@ -206,6 +206,7 @@ impl Service for TimeoutService {
206
206
  type Lister = TimeoutWrapper<oio::Lister>;
207
207
  type Deleter = TimeoutWrapper<oio::Deleter>;
208
208
  type Copier = TimeoutWrapper<oio::Copier>;
209
+ type Composer = TimeoutWrapper<oio::Composer>;
209
210
 
210
211
  fn info(&self) -> ServiceInfo {
211
212
  self.inner.info()
@@ -243,10 +244,15 @@ impl Service for TimeoutService {
243
244
  from: &str,
244
245
  to: &str,
245
246
  args: OpCopy,
246
- opts: OpCopier,
247
247
  ) -> Result<Self::Copier> {
248
248
  self.inner
249
- .copy(ctx, from, to, args, opts)
249
+ .copy(ctx, from, to, args)
250
+ .map(|c| TimeoutWrapper::new(c, self.io_timeout))
251
+ }
252
+
253
+ fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
254
+ self.inner
255
+ .compose(ctx, to, args)
250
256
  .map(|c| TimeoutWrapper::new(c, self.io_timeout))
251
257
  }
252
258
 
@@ -261,6 +267,16 @@ impl Service for TimeoutService {
261
267
  .await
262
268
  }
263
269
 
270
+ async fn restore(
271
+ &self,
272
+ ctx: &OperationContext,
273
+ path: &str,
274
+ args: OpRestore,
275
+ ) -> Result<RpRestore> {
276
+ self.timeout(Operation::Restore, self.inner.restore(ctx, path, args))
277
+ .await
278
+ }
279
+
264
280
  async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
265
281
  self.timeout(Operation::Stat, self.inner.stat(ctx, path, args))
266
282
  .await
@@ -374,6 +390,11 @@ impl<R: oio::Write> oio::Write for TimeoutWrapper<R> {
374
390
  Self::io_timeout(self.timeout, Operation::Write.into_static(), fut).await
375
391
  }
376
392
 
393
+ async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
394
+ let fut = self.inner.copy_from(path, args, range);
395
+ Self::io_timeout(self.timeout, Operation::Write.into_static(), fut).await
396
+ }
397
+
377
398
  async fn close(&mut self) -> Result<Metadata> {
378
399
  let fut = self.inner.close();
379
400
  Self::io_timeout(self.timeout, Operation::Write.into_static(), fut).await
@@ -421,6 +442,18 @@ impl<C: oio::Copy> oio::Copy for TimeoutWrapper<C> {
421
442
  }
422
443
  }
423
444
 
445
+ impl<C: oio::Compose> oio::Compose for TimeoutWrapper<C> {
446
+ async fn compose(&mut self, path: &str, args: OpRead) -> Result<()> {
447
+ let fut = self.inner.compose(path, args);
448
+ Self::io_timeout(self.timeout, Operation::Compose.into_static(), fut).await
449
+ }
450
+
451
+ async fn close(&mut self) -> Result<Metadata> {
452
+ let fut = self.inner.close();
453
+ Self::io_timeout(self.timeout, Operation::Compose.into_static(), fut).await
454
+ }
455
+ }
456
+
424
457
  #[cfg(test)]
425
458
  mod tests {
426
459
  use std::future::pending;
@@ -439,6 +472,7 @@ mod tests {
439
472
  type Lister = MockLister;
440
473
  type Deleter = MockDeleter;
441
474
  type Copier = MockCopier;
475
+ type Composer = ();
442
476
 
443
477
  fn info(&self) -> ServiceInfo {
444
478
  ServiceInfo::with_scheme("mock")
@@ -494,14 +528,7 @@ mod tests {
494
528
  Ok(MockLister)
495
529
  }
496
530
 
497
- fn copy(
498
- &self,
499
- _: &OperationContext,
500
- _: &str,
501
- _: &str,
502
- _: OpCopy,
503
- _: OpCopier,
504
- ) -> Result<Self::Copier> {
531
+ fn copy(&self, _: &OperationContext, _: &str, _: &str, _: OpCopy) -> Result<Self::Copier> {
505
532
  Ok(MockCopier)
506
533
  }
507
534
 
@@ -651,9 +678,7 @@ mod tests {
651
678
  .with_io_timeout(Duration::from_millis(100))
652
679
  .apply_service(Arc::new(MockService));
653
680
  let ctx = OperationContext::new();
654
- let mut copier = service
655
- .copy(&ctx, "f", "t", OpCopy::default(), OpCopier::default())
656
- .unwrap();
681
+ let mut copier = service.copy(&ctx, "f", "t", OpCopy::default()).unwrap();
657
682
 
658
683
  let err = copier.next().await.unwrap_err();
659
684
  assert!(err.to_string().contains("timeout"));
@@ -34,13 +34,13 @@ all-features = true
34
34
  [dependencies]
35
35
  futures = { workspace = true }
36
36
  http = { workspace = true }
37
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
37
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
38
38
  tracing = "0.1"
39
39
 
40
40
  [dev-dependencies]
41
41
  anyhow = "1.0"
42
42
  dotenvy = "0.15"
43
- opendal-core = { path = "../../core", version = "0.58.1" }
43
+ opendal-core = { path = "../../core", version = "0.59.0" }
44
44
  opentelemetry = { version = "0.32.0", default-features = false, features = [
45
45
  "trace",
46
46
  ] }
@@ -224,6 +224,7 @@ impl Service for TracingService {
224
224
  type Lister = TracingWrapper<oio::Lister>;
225
225
  type Deleter = TracingWrapper<oio::Deleter>;
226
226
  type Copier = oio::Copier;
227
+ type Composer = oio::Composer;
227
228
 
228
229
  fn info(&self) -> ServiceInfo {
229
230
  self.inner.info()
@@ -233,6 +234,10 @@ impl Service for TracingService {
233
234
  self.inner.capability()
234
235
  }
235
236
 
237
+ fn compose(&self, ctx: &OperationContext, to: &str, args: OpCompose) -> Result<Self::Composer> {
238
+ self.inner.compose(ctx, to, args)
239
+ }
240
+
236
241
  async fn create_dir(
237
242
  &self,
238
243
  ctx: &OperationContext,
@@ -266,11 +271,10 @@ impl Service for TracingService {
266
271
  from: &str,
267
272
  to: &str,
268
273
  args: OpCopy,
269
- opts: OpCopier,
270
274
  ) -> Result<Self::Copier> {
271
- let span = span!(Level::DEBUG, "copy", from, to, ?args, ?opts);
275
+ let span = span!(Level::DEBUG, "copy", from, to, ?args);
272
276
  let _guard = span.enter();
273
- self.inner.copy(ctx, from, to, args, opts)
277
+ self.inner.copy(ctx, from, to, args)
274
278
  }
275
279
 
276
280
  async fn rename(
@@ -287,6 +291,16 @@ impl Service for TracingService {
287
291
  .await
288
292
  }
289
293
 
294
+ async fn restore(
295
+ &self,
296
+ ctx: &OperationContext,
297
+ path: &str,
298
+ args: OpRestore,
299
+ ) -> Result<RpRestore> {
300
+ let span = span!(Level::DEBUG, "restore", path, ?args);
301
+ self.inner.restore(ctx, path, args).instrument(span).await
302
+ }
303
+
290
304
  async fn stat(&self, ctx: &OperationContext, path: &str, args: OpStat) -> Result<RpStat> {
291
305
  let span = span!(Level::DEBUG, "stat", path, ?args);
292
306
  self.inner.stat(ctx, path, args).instrument(span).await
@@ -354,6 +368,13 @@ impl<R: oio::Write> oio::Write for TracingWrapper<R> {
354
368
  self.inner.write(bs).instrument(self.span.clone()).await
355
369
  }
356
370
 
371
+ async fn copy_from(&mut self, path: &str, args: OpRead, range: BytesRange) -> Result<()> {
372
+ self.inner
373
+ .copy_from(path, args, range)
374
+ .instrument(self.span.clone())
375
+ .await
376
+ }
377
+
357
378
  async fn abort(&mut self) -> Result<()> {
358
379
  self.inner.abort().instrument(self.span.clone()).await
359
380
  }
@@ -32,11 +32,11 @@ version = { workspace = true }
32
32
  all-features = true
33
33
 
34
34
  [dependencies]
35
+ asyncband = { workspace = true }
35
36
  bytes = { workspace = true }
36
37
  http = { workspace = true }
37
38
  log = { workspace = true }
38
- mea = { workspace = true }
39
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
39
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
40
40
  serde = { workspace = true, features = ["derive"] }
41
41
  serde_json = { workspace = true }
42
42