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
@@ -19,8 +19,8 @@ use std::sync::Arc;
19
19
 
20
20
  use http::StatusCode;
21
21
 
22
- use super::core::IpmfsCore;
23
22
  use super::core::parse_error;
23
+ use super::core::{ErrorContext, IpmfsCore};
24
24
  use opendal_core::raw::*;
25
25
  use opendal_core::*;
26
26
 
@@ -43,8 +43,11 @@ impl oio::OneShotWrite for IpmfsWriter {
43
43
  let status = resp.status();
44
44
 
45
45
  match status {
46
- StatusCode::CREATED | StatusCode::OK => Ok(Metadata::default()),
47
- _ => Err(parse_error(resp)),
46
+ StatusCode::CREATED | StatusCode::OK => Ok(MetadataBuilder::unknown().build()),
47
+ _ => Err(parse_error(
48
+ ErrorContext::new(ServiceOperation("Add")),
49
+ resp,
50
+ )),
48
51
  }
49
52
  }
50
53
  }
@@ -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
 
@@ -18,18 +18,18 @@
18
18
  use std::fmt::Debug;
19
19
  use std::sync::Arc;
20
20
 
21
+ use asyncband::mutex::Mutex;
22
+ use asyncband::once::OnceCell;
21
23
  use bytes::Buf;
22
24
  use http::StatusCode;
23
25
  use log::debug;
24
- use mea::mutex::Mutex;
25
- use mea::once::OnceCell;
26
26
 
27
27
  use super::KOOFR_SCHEME;
28
28
  use super::config::KoofrConfig;
29
29
  use super::core::File;
30
- use super::core::KoofrCore;
31
30
  use super::core::KoofrSigner;
32
31
  use super::core::parse_error;
32
+ use super::core::{ErrorContext, KoofrCore};
33
33
  use super::deleter::KoofrDeleter;
34
34
  use super::lister::KoofrLister;
35
35
  use super::reader::*;
@@ -190,6 +190,7 @@ impl Service for KoofrBackend {
190
190
  type Lister = oio::PageLister<KoofrLister>;
191
191
  type Deleter = oio::OneShotDeleter<KoofrDeleter>;
192
192
  type Copier = oio::OneShotCopier;
193
+ type Composer = ();
193
194
 
194
195
  fn info(&self) -> ServiceInfo {
195
196
  self.core.info.clone()
@@ -231,15 +232,21 @@ impl Service for KoofrBackend {
231
232
  EntryMode::FILE
232
233
  };
233
234
 
234
- let mut md = Metadata::new(mode);
235
+ let mut md = if mode == EntryMode::FILE {
236
+ MetadataBuilder::file(file.size)
237
+ } else {
238
+ MetadataBuilder::dir()
239
+ };
235
240
 
236
- md.set_content_length(file.size)
237
- .set_content_type(&file.content_type)
238
- .set_last_modified(Timestamp::from_millisecond(file.modified)?);
241
+ md.content_type(&file.content_type)
242
+ .last_modified(Timestamp::from_millisecond(file.modified)?);
239
243
 
240
- Ok(RpStat::new(md))
244
+ Ok(RpStat::new(md.build()))
241
245
  }
242
- _ => Err(parse_error(resp)),
246
+ _ => Err(parse_error(
247
+ ErrorContext::new(ServiceOperation("FilesInfo")),
248
+ resp,
249
+ )),
243
250
  }
244
251
  }
245
252
  fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
@@ -292,33 +299,49 @@ impl Service for KoofrBackend {
292
299
  ctx: &OperationContext,
293
300
  from: &str,
294
301
  to: &str,
295
- _args: OpCopy,
296
- _opts: OpCopier,
302
+ args: OpCopy,
297
303
  ) -> Result<Self::Copier> {
304
+ let backend = self.clone();
298
305
  let core = self.core.clone();
299
306
  let ctx = ctx.clone();
300
307
  let from = from.to_string();
301
308
  let to = to.to_string();
309
+ let source_content_length_hint = args.source_content_length_hint();
302
310
 
303
311
  Ok(oio::OneShotCopier::new(async move {
312
+ let source_size = match source_content_length_hint {
313
+ Some(size) => size,
314
+ None => backend
315
+ .stat(&ctx, &from, OpStat::default())
316
+ .await?
317
+ .into_metadata()
318
+ .content_length(),
319
+ };
320
+
304
321
  core.ensure_dir_exists(&ctx, &to).await?;
305
322
  if from == to {
306
- Ok(Metadata::default())
323
+ Ok(MetadataBuilder::file(source_size).build())
307
324
  } else {
308
325
  let resp = core.remove(&ctx, &to).await?;
309
326
 
310
327
  let status = resp.status();
311
328
 
312
329
  if status != StatusCode::OK && status != StatusCode::NOT_FOUND {
313
- Err(parse_error(resp))
330
+ Err(parse_error(
331
+ ErrorContext::new(ServiceOperation("FilesRemove")),
332
+ resp,
333
+ ))
314
334
  } else {
315
335
  let resp = core.copy(&ctx, &from, &to).await?;
316
336
 
317
337
  let status = resp.status();
318
338
 
319
339
  match status {
320
- StatusCode::OK => Ok(Metadata::default()),
321
- _ => Err(parse_error(resp)),
340
+ StatusCode::OK => Ok(MetadataBuilder::file(source_size).build()),
341
+ _ => Err(parse_error(
342
+ ErrorContext::new(ServiceOperation("FilesCopy")),
343
+ resp,
344
+ )),
322
345
  }
323
346
  }
324
347
  }
@@ -343,7 +366,10 @@ impl Service for KoofrBackend {
343
366
  let status = resp.status();
344
367
 
345
368
  if status != StatusCode::OK && status != StatusCode::NOT_FOUND {
346
- return Err(parse_error(resp));
369
+ return Err(parse_error(
370
+ ErrorContext::new(ServiceOperation("FilesRemove")),
371
+ resp,
372
+ ));
347
373
  }
348
374
 
349
375
  let resp = self.core.move_object(ctx, from, to).await?;
@@ -352,7 +378,10 @@ impl Service for KoofrBackend {
352
378
 
353
379
  match status {
354
380
  StatusCode::OK => Ok(RpRename::default()),
355
- _ => Err(parse_error(resp)),
381
+ _ => Err(parse_error(
382
+ ErrorContext::new(ServiceOperation("FilesMove")),
383
+ resp,
384
+ )),
356
385
  }
357
386
  }
358
387
 
@@ -19,6 +19,8 @@ use std::collections::VecDeque;
19
19
  use std::fmt::Debug;
20
20
  use std::sync::Arc;
21
21
 
22
+ use asyncband::mutex::Mutex;
23
+ use asyncband::once::OnceCell;
22
24
  use bytes::Buf;
23
25
  use bytes::Bytes;
24
26
  use http::Request;
@@ -26,8 +28,6 @@ use http::Response;
26
28
  use http::StatusCode;
27
29
  use http::header;
28
30
  use http::request;
29
- use mea::mutex::Mutex;
30
- use mea::once::OnceCell;
31
31
  use serde::Deserialize;
32
32
  use serde_json::json;
33
33
 
@@ -88,7 +88,10 @@ impl KoofrCore {
88
88
  let status = resp.status();
89
89
 
90
90
  if status != StatusCode::OK {
91
- return Err(parse_error(resp));
91
+ return Err(parse_error(
92
+ ErrorContext::new(ServiceOperation("ListMounts")),
93
+ resp,
94
+ ));
92
95
  }
93
96
 
94
97
  let bs = resp.into_body();
@@ -139,7 +142,10 @@ impl KoofrCore {
139
142
  let status = resp.status();
140
143
 
141
144
  if status != StatusCode::OK {
142
- return Err(parse_error(resp));
145
+ return Err(parse_error(
146
+ ErrorContext::new(ServiceOperation("Authenticate")),
147
+ resp,
148
+ ));
143
149
  }
144
150
 
145
151
  let bs = resp.into_body();
@@ -219,11 +225,17 @@ impl KoofrCore {
219
225
  // When the directory already exists, Koofr returns 400 Bad Request.
220
226
  // We should treat it as success.
221
227
  StatusCode::OK | StatusCode::CREATED | StatusCode::BAD_REQUEST => Ok(()),
222
- _ => Err(parse_error(resp)),
228
+ _ => Err(parse_error(
229
+ ErrorContext::new(ServiceOperation("CreateFolder")),
230
+ resp,
231
+ )),
223
232
  }
224
233
  }
225
234
  StatusCode::OK => Ok(()),
226
- _ => Err(parse_error(resp)),
235
+ _ => Err(parse_error(
236
+ ErrorContext::new(ServiceOperation("FilesInfo")),
237
+ resp,
238
+ )),
227
239
  }
228
240
  }
229
241
 
@@ -493,62 +505,66 @@ pub struct File {
493
505
  pub content_type: String,
494
506
  }
495
507
 
496
- mod error {
497
- use http::Response;
498
-
499
- use opendal_core::raw::*;
500
- use opendal_core::*;
508
+ /// Context needed to classify an error from this service.
509
+ #[derive(Clone, Copy, Debug)]
510
+ pub(crate) struct ErrorContext {
511
+ service_operation: ServiceOperation,
512
+ }
501
513
 
502
- /// Parse error response into Error.
503
- pub(crate) fn parse_error(resp: Response<Buffer>) -> Error {
504
- let (parts, body) = resp.into_parts();
505
- let bs = body.to_bytes();
514
+ impl ErrorContext {
515
+ pub(crate) const fn new(service_operation: ServiceOperation) -> Self {
516
+ Self { service_operation }
517
+ }
518
+ }
506
519
 
507
- let (kind, retryable) = match parts.status.as_u16() {
508
- 403 => (ErrorKind::PermissionDenied, false),
509
- 404 => (ErrorKind::NotFound, false),
510
- 304 | 412 => (ErrorKind::ConditionNotMatch, false),
511
- // Service like Koofr could return 499 error with a message like:
512
- // Client Disconnect, we should retry it.
513
- 499 => (ErrorKind::Unexpected, true),
514
- 500 | 502 | 503 | 504 => (ErrorKind::Unexpected, true),
515
- _ => (ErrorKind::Unexpected, false),
516
- };
520
+ /// Parse an error response using its service request context.
521
+ pub(crate) fn parse_error(ctx: ErrorContext, resp: Response<Buffer>) -> Error {
522
+ let (parts, body) = resp.into_parts();
523
+ let bs = body.to_bytes();
517
524
 
518
- let message = String::from_utf8_lossy(&bs).into_owned();
525
+ let (kind, retryable) = match parts.status.as_u16() {
526
+ 403 => (ErrorKind::PermissionDenied, false),
527
+ 404 => (ErrorKind::NotFound, false),
528
+ 304 | 412 => (ErrorKind::ConditionNotMatch, false),
529
+ // Service like Koofr could return 499 error with a message like:
530
+ // Client Disconnect, we should retry it.
531
+ 499 => (ErrorKind::Unexpected, true),
532
+ 500 | 502 | 503 | 504 => (ErrorKind::Unexpected, true),
533
+ _ => (ErrorKind::Unexpected, false),
534
+ };
519
535
 
520
- let mut err = Error::new(kind, message);
536
+ let message = String::from_utf8_lossy(&bs).into_owned();
521
537
 
522
- err = with_error_response_context(err, parts);
538
+ let mut err = Error::new(kind, message);
523
539
 
524
- if retryable {
525
- err = err.set_temporary();
526
- }
540
+ err = err.with_context("service_operation", ctx.service_operation.0);
541
+ err = with_error_response_context(err, parts);
527
542
 
528
- err
543
+ if retryable {
544
+ err = err.set_temporary();
529
545
  }
530
546
 
531
- #[cfg(test)]
532
- mod test {
533
- use http::StatusCode;
547
+ err
548
+ }
534
549
 
535
- use super::*;
550
+ #[cfg(test)]
551
+ mod tests {
552
+ use http::StatusCode;
536
553
 
537
- #[tokio::test]
538
- async fn test_parse_error() {
539
- let err_res = vec![(r#""#, ErrorKind::NotFound, StatusCode::NOT_FOUND)];
554
+ use super::*;
540
555
 
541
- for res in err_res {
542
- let bs = bytes::Bytes::from(res.0);
543
- let body = Buffer::from(bs);
544
- let resp = Response::builder().status(res.2).body(body).unwrap();
556
+ #[tokio::test]
557
+ async fn test_parse_error() {
558
+ let err_res = vec![(r#""#, ErrorKind::NotFound, StatusCode::NOT_FOUND)];
545
559
 
546
- let err = parse_error(resp);
560
+ for res in err_res {
561
+ let bs = bytes::Bytes::from(res.0);
562
+ let body = Buffer::from(bs);
563
+ let resp = Response::builder().status(res.2).body(body).unwrap();
547
564
 
548
- assert_eq!(err.kind(), res.1);
549
- }
565
+ let err = parse_error(ErrorContext::new(ServiceOperation("Test")), resp);
566
+
567
+ assert_eq!(err.kind(), res.1);
550
568
  }
551
569
  }
552
570
  }
553
-
554
- pub(super) use error::*;
@@ -45,7 +45,10 @@ impl oio::OneShotDelete for KoofrDeleter {
45
45
  StatusCode::OK => Ok(()),
46
46
  // Allow 404 when deleting a non-existing object
47
47
  StatusCode::NOT_FOUND => Ok(()),
48
- _ => Err(parse_error(resp)),
48
+ _ => Err(parse_error(
49
+ ErrorContext::new(ServiceOperation("FilesRemove")),
50
+ resp,
51
+ )),
49
52
  }
50
53
  }
51
54
  }
@@ -19,11 +19,10 @@ use std::sync::Arc;
19
19
 
20
20
  use bytes::Buf;
21
21
 
22
- use super::core::KoofrCore;
23
22
  use super::core::ListResponse;
24
23
  use super::core::parse_error;
25
- use opendal_core::EntryMode;
26
- use opendal_core::Metadata;
24
+ use super::core::{ErrorContext, KoofrCore};
25
+ use opendal_core::MetadataBuilder;
27
26
  use opendal_core::OperationContext;
28
27
  use opendal_core::Result;
29
28
  use opendal_core::raw::oio::Entry;
@@ -58,7 +57,10 @@ impl oio::PageList for KoofrLister {
58
57
  match resp.status() {
59
58
  http::StatusCode::OK => {}
60
59
  _ => {
61
- return Err(parse_error(resp));
60
+ return Err(parse_error(
61
+ ErrorContext::new(ServiceOperation("FilesList")),
62
+ resp,
63
+ ));
62
64
  }
63
65
  }
64
66
 
@@ -72,13 +74,12 @@ impl oio::PageList for KoofrLister {
72
74
 
73
75
  let entry = if file.ty == "dir" {
74
76
  let path = format!("{path}/");
75
- Entry::new(&path, Metadata::new(EntryMode::DIR))
77
+ Entry::new(&path, MetadataBuilder::dir().build())
76
78
  } else {
77
- let m = Metadata::new(EntryMode::FILE)
78
- .with_content_length(file.size)
79
- .with_content_type(file.content_type)
80
- .with_last_modified(Timestamp::from_millisecond(file.modified)?);
81
- Entry::new(&path, m)
79
+ let mut m = MetadataBuilder::file(file.size);
80
+ m.content_type(file.content_type)
81
+ .last_modified(Timestamp::from_millisecond(file.modified)?);
82
+ Entry::new(&path, m.build())
82
83
  };
83
84
 
84
85
  ctx.entries.push_back(entry);
@@ -16,7 +16,7 @@
16
16
  // under the License.
17
17
 
18
18
  use super::backend::*;
19
- use super::core::parse_error;
19
+ use super::core::{ErrorContext, parse_error};
20
20
  use http::Response;
21
21
  use http::StatusCode;
22
22
  use opendal_core::raw::*;
@@ -54,7 +54,10 @@ impl oio::StreamRead for KoofrReader {
54
54
  _ => {
55
55
  let (part, mut body) = resp.into_parts();
56
56
  let buf = body.to_buffer().await?;
57
- return Err(parse_error(Response::from_parts(part, buf)));
57
+ return Err(parse_error(
58
+ ErrorContext::new(ServiceOperation("FilesGet")),
59
+ Response::from_parts(part, buf),
60
+ ));
58
61
  }
59
62
  };
60
63
 
@@ -21,8 +21,8 @@ use bytes::Buf;
21
21
  use http::StatusCode;
22
22
 
23
23
  use super::core::File;
24
- use super::core::KoofrCore;
25
24
  use super::core::parse_error;
25
+ use super::core::{ErrorContext, KoofrCore};
26
26
  use opendal_core::raw::*;
27
27
  use opendal_core::*;
28
28
 
@@ -46,12 +46,15 @@ impl KoofrWriter {
46
46
  EntryMode::FILE
47
47
  };
48
48
 
49
- let mut meta = Metadata::new(mode);
50
- meta.set_content_length(file.size);
51
- meta.set_content_type(&file.content_type);
52
- meta.set_last_modified(Timestamp::from_millisecond(file.modified)?);
49
+ let mut meta = if mode == EntryMode::FILE {
50
+ MetadataBuilder::file(file.size)
51
+ } else {
52
+ MetadataBuilder::dir()
53
+ };
54
+ meta.content_type(&file.content_type);
55
+ meta.last_modified(Timestamp::from_millisecond(file.modified)?);
53
56
 
54
- Ok(meta)
57
+ Ok(meta.build())
55
58
  }
56
59
  }
57
60
 
@@ -71,7 +74,10 @@ impl oio::OneShotWrite for KoofrWriter {
71
74
  let metadata = Self::parse_metadata(&file)?;
72
75
  Ok(metadata)
73
76
  }
74
- _ => Err(parse_error(resp)),
77
+ _ => Err(parse_error(
78
+ ErrorContext::new(ServiceOperation("FilesPut")),
79
+ resp,
80
+ )),
75
81
  }
76
82
  }
77
83
  }
@@ -35,7 +35,7 @@ all-features = true
35
35
  bytes = { workspace = true }
36
36
  http = { workspace = true }
37
37
  log = { workspace = true }
38
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
38
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
39
39
  serde = { workspace = true, features = ["derive"] }
40
40
  serde_json = { workspace = true }
41
41
 
@@ -25,9 +25,9 @@ use opendal_core::*;
25
25
 
26
26
  use super::LAKEFS_SCHEME;
27
27
  use super::config::LakefsConfig;
28
- use super::core::LakefsCore;
29
28
  use super::core::LakefsStatus;
30
29
  use super::core::parse_error;
30
+ use super::core::{ErrorContext, LakefsCore};
31
31
  use super::deleter::LakefsDeleter;
32
32
  use super::lister::LakefsLister;
33
33
  use super::reader::*;
@@ -191,6 +191,7 @@ impl Service for LakefsBackend {
191
191
  type Lister = oio::PageLister<LakefsLister>;
192
192
  type Deleter = oio::OneShotDeleter<LakefsDeleter>;
193
193
  type Copier = oio::OneShotCopier;
194
+ type Composer = ();
194
195
 
195
196
  fn info(&self) -> ServiceInfo {
196
197
  self.core.info.clone()
@@ -215,7 +216,7 @@ impl Service for LakefsBackend {
215
216
  async fn stat(&self, ctx: &OperationContext, path: &str, _: OpStat) -> Result<RpStat> {
216
217
  // Stat root always returns a DIR.
217
218
  if path == "/" {
218
- return Ok(RpStat::new(Metadata::new(EntryMode::DIR)));
219
+ return Ok(RpStat::new(MetadataBuilder::dir().build()));
219
220
  }
220
221
 
221
222
  let resp = self.core.get_object_metadata(ctx, path).await?;
@@ -230,11 +231,14 @@ impl Service for LakefsBackend {
230
231
  serde_json::from_reader(bs.reader()).map_err(new_json_deserialize_error)?;
231
232
 
232
233
  // Use the helper function to parse LakefsStatus into Metadata
233
- let meta = LakefsCore::parse_lakefs_status_into_metadata(&decoded_response);
234
+ let meta = LakefsCore::parse_lakefs_status_into_metadata(&decoded_response)?;
234
235
 
235
236
  Ok(RpStat::new(meta))
236
237
  }
237
- _ => Err(parse_error(resp)),
238
+ _ => Err(parse_error(
239
+ ErrorContext::new(ServiceOperation("StatObject")),
240
+ resp,
241
+ )),
238
242
  }
239
243
  }
240
244
  fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
@@ -296,21 +300,34 @@ impl Service for LakefsBackend {
296
300
  ctx: &OperationContext,
297
301
  from: &str,
298
302
  to: &str,
299
- _args: OpCopy,
300
- _opts: OpCopier,
303
+ args: OpCopy,
301
304
  ) -> Result<Self::Copier> {
305
+ let backend = self.clone();
302
306
  let core = self.core.clone();
303
307
  let ctx = ctx.clone();
304
308
  let from = from.to_string();
305
309
  let to = to.to_string();
310
+ let source_content_length_hint = args.source_content_length_hint();
306
311
 
307
312
  Ok(oio::OneShotCopier::new(async move {
313
+ let source_size = match source_content_length_hint {
314
+ Some(size) => size,
315
+ None => backend
316
+ .stat(&ctx, &from, OpStat::default())
317
+ .await?
318
+ .into_metadata()
319
+ .content_length(),
320
+ };
321
+
308
322
  let resp = core.copy_object(&ctx, &from, &to).await?;
309
323
  let status = resp.status();
310
324
 
311
325
  match status {
312
- StatusCode::CREATED => Ok(Metadata::default()),
313
- _ => Err(parse_error(resp)),
326
+ StatusCode::CREATED => Ok(MetadataBuilder::file(source_size).build()),
327
+ _ => Err(parse_error(
328
+ ErrorContext::new(ServiceOperation("CopyObject")),
329
+ resp,
330
+ )),
314
331
  }
315
332
  }))
316
333
  }