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
@@ -140,7 +140,10 @@ impl WebdavCore {
140
140
 
141
141
  let resp = ctx.http_transport().send(req).await?;
142
142
  if !resp.status().is_success() {
143
- return Err(parse_error(resp));
143
+ return Err(parse_error(
144
+ ErrorContext::new(ServiceOperation("Propfind")),
145
+ resp,
146
+ ));
144
147
  }
145
148
 
146
149
  let bs = resp.into_body();
@@ -155,15 +158,15 @@ impl WebdavCore {
155
158
  )
156
159
  })?;
157
160
 
158
- let mut metadata = parse_propstats(&propfind_resp.propstat)?;
161
+ let mut metadata = parse_propstats(&propfind_resp.propstat)?.into_builder();
159
162
 
160
163
  // Parse user metadata from the raw XML response using configured namespace
161
164
  let user_metadata = parse_user_metadata_from_xml(&xml_str, &self.user_metadata_uri);
162
165
  if !user_metadata.is_empty() {
163
- metadata = metadata.with_user_metadata(user_metadata);
166
+ metadata.user_metadata(user_metadata);
164
167
  }
165
168
 
166
- Ok(metadata)
169
+ Ok(metadata.build())
167
170
  }
168
171
 
169
172
  pub async fn webdav_get(
@@ -324,8 +327,6 @@ impl WebdavCore {
324
327
  from: &str,
325
328
  to: &str,
326
329
  ) -> Result<Response<Buffer>> {
327
- // Check if source file exists.
328
- let _ = self.webdav_stat(ctx, from).await?;
329
330
  // Make sure target's dir is exist.
330
331
  self.webdav_mkcol(ctx, get_parent(to)).await?;
331
332
 
@@ -495,7 +496,10 @@ impl WebdavCore {
495
496
 
496
497
  Ok(())
497
498
  }
498
- _ => Err(parse_error(resp)),
499
+ _ => Err(parse_error(
500
+ ErrorContext::new(ServiceOperation("Mkcol")),
501
+ resp,
502
+ )),
499
503
  }
500
504
  }
501
505
  }
@@ -823,21 +827,26 @@ pub fn parse_propstat(propstat: &Propstat) -> Result<Metadata> {
823
827
  } else {
824
828
  EntryMode::FILE
825
829
  };
826
- let mut m = Metadata::new(mode);
827
-
828
- if let Some(v) = getcontentlength {
829
- let content_length = v.parse::<u64>().map_err(|err| {
830
- Error::new(ErrorKind::Unexpected, "parse webdav content length").set_source(err)
830
+ let mut m = if mode == EntryMode::FILE {
831
+ let content_length = getcontentlength.as_ref().ok_or_else(|| {
832
+ Error::new(
833
+ ErrorKind::Unexpected,
834
+ "webdav response does not contain file content length",
835
+ )
831
836
  })?;
832
- m.set_content_length(content_length);
833
- }
837
+ MetadataBuilder::file(content_length.parse::<u64>().map_err(|err| {
838
+ Error::new(ErrorKind::Unexpected, "parse webdav content length").set_source(err)
839
+ })?)
840
+ } else {
841
+ MetadataBuilder::dir()
842
+ };
834
843
 
835
844
  if let Some(v) = getcontenttype {
836
- m.set_content_type(v);
845
+ m.content_type(v);
837
846
  }
838
847
 
839
848
  if let Some(v) = getetag {
840
- m.set_etag(v);
849
+ m.etag(v);
841
850
  }
842
851
 
843
852
  // https://www.rfc-editor.org/rfc/rfc4918#section-14.18
@@ -847,10 +856,10 @@ pub fn parse_propstat(propstat: &Propstat) -> Result<Metadata> {
847
856
  "propfind response missing getlastmodified",
848
857
  ));
849
858
  };
850
- m.set_last_modified(Timestamp::parse_rfc2822(getlastmodified)?);
859
+ m.last_modified(Timestamp::parse_rfc2822(getlastmodified)?);
851
860
 
852
861
  // the storage services have returned all the properties
853
- Ok(m)
862
+ Ok(m.build())
854
863
  }
855
864
 
856
865
  pub fn parse_propstats(propstats: &[Propstat]) -> Result<Metadata> {
@@ -1100,11 +1109,12 @@ mod tests {
1100
1109
  resourcetype: ResourceTypeContainer::default(),
1101
1110
  },
1102
1111
  },
1103
- new_propstat("HTTP/1.1 200 OK", None),
1112
+ new_propstat("HTTP/1.1 200 OK", Some("0")),
1104
1113
  ];
1105
1114
 
1106
1115
  let meta = parse_propstats(&propstats).unwrap();
1107
1116
  assert!(meta.is_file());
1117
+ assert_eq!(meta.content_length(), 0);
1108
1118
  }
1109
1119
 
1110
1120
  #[test]
@@ -1622,52 +1632,99 @@ mod tests {
1622
1632
 
1623
1633
  assert!(check_proppatch_response(xml).is_ok());
1624
1634
  }
1625
- }
1626
-
1627
- mod error {
1628
- use http::Response;
1629
- use http::StatusCode;
1630
-
1631
- use opendal_core::raw::*;
1632
- use opendal_core::*;
1633
-
1634
- /// Parse error response into Error.
1635
- pub(crate) fn parse_error(resp: Response<Buffer>) -> Error {
1636
- let (parts, body) = resp.into_parts();
1637
- let bs = body.to_bytes();
1638
-
1639
- let (kind, retryable) = match parts.status {
1640
- StatusCode::NOT_FOUND => (ErrorKind::NotFound, false),
1641
- // Some services (like owncloud) return 403 while file locked.
1642
- StatusCode::FORBIDDEN => (ErrorKind::PermissionDenied, true),
1643
- // RFC 7232: 412 means an If-Match / If-Unmodified-Since
1644
- // precondition failed; 304 means an If-None-Match /
1645
- // If-Modified-Since precondition matched. Surface both as
1646
- // ConditionNotMatch so callers can branch on it.
1647
- StatusCode::PRECONDITION_FAILED | StatusCode::NOT_MODIFIED => {
1648
- (ErrorKind::ConditionNotMatch, false)
1649
- }
1650
- // Allowing retry for resource locked.
1651
- StatusCode::LOCKED => (ErrorKind::Unexpected, true),
1652
- StatusCode::INTERNAL_SERVER_ERROR
1653
- | StatusCode::BAD_GATEWAY
1654
- | StatusCode::SERVICE_UNAVAILABLE
1655
- | StatusCode::GATEWAY_TIMEOUT => (ErrorKind::Unexpected, true),
1656
- _ => (ErrorKind::Unexpected, false),
1657
- };
1658
1635
 
1659
- let message = String::from_utf8_lossy(&bs);
1636
+ #[test]
1637
+ fn test_parse_error_maps_missing_if_match_to_not_found() {
1638
+ let resp = Response::builder()
1639
+ .status(StatusCode::PRECONDITION_FAILED)
1640
+ .body(Buffer::from(
1641
+ "An If-Match header was specified and the resource did not exist",
1642
+ ))
1643
+ .unwrap();
1644
+
1645
+ let err = parse_error(
1646
+ ErrorContext::new(ServiceOperation("Get")).with_if_match(true),
1647
+ resp,
1648
+ );
1649
+ assert_eq!(err.kind(), ErrorKind::NotFound);
1650
+ }
1660
1651
 
1661
- let mut err = Error::new(kind, message);
1652
+ #[test]
1653
+ fn test_parse_error_preserves_etag_mismatch() {
1654
+ let resp = Response::builder()
1655
+ .status(StatusCode::PRECONDITION_FAILED)
1656
+ .body(Buffer::from("The ETag did not match"))
1657
+ .unwrap();
1658
+
1659
+ let err = parse_error(
1660
+ ErrorContext::new(ServiceOperation("Get")).with_if_match(true),
1661
+ resp,
1662
+ );
1663
+ assert_eq!(err.kind(), ErrorKind::ConditionNotMatch);
1664
+ }
1665
+ }
1662
1666
 
1663
- err = with_error_response_context(err, parts);
1667
+ /// Context needed to classify an error from this service.
1668
+ #[derive(Clone, Copy, Debug)]
1669
+ pub(crate) struct ErrorContext {
1670
+ service_operation: ServiceOperation,
1671
+ if_match: bool,
1672
+ }
1664
1673
 
1665
- if retryable {
1666
- err = err.set_temporary();
1674
+ impl ErrorContext {
1675
+ pub(crate) const fn new(service_operation: ServiceOperation) -> Self {
1676
+ Self {
1677
+ service_operation,
1678
+ if_match: false,
1667
1679
  }
1680
+ }
1668
1681
 
1669
- err
1682
+ pub(crate) const fn with_if_match(mut self, if_match: bool) -> Self {
1683
+ self.if_match = if_match;
1684
+ self
1670
1685
  }
1671
1686
  }
1672
1687
 
1673
- pub(super) use error::*;
1688
+ /// Parse an error response using its service request context.
1689
+ pub(crate) fn parse_error(ctx: ErrorContext, resp: Response<Buffer>) -> Error {
1690
+ let (parts, body) = resp.into_parts();
1691
+ let bs = body.to_bytes();
1692
+
1693
+ let message = String::from_utf8_lossy(&bs);
1694
+
1695
+ let (kind, retryable) = match parts.status {
1696
+ StatusCode::NOT_FOUND => (ErrorKind::NotFound, false),
1697
+ // Some services (like owncloud) return 403 while file locked.
1698
+ StatusCode::FORBIDDEN => (ErrorKind::PermissionDenied, true),
1699
+ // RFC 7232: 412 means an If-Match / If-Unmodified-Since
1700
+ // precondition failed; 304 means an If-None-Match /
1701
+ // If-Modified-Since precondition matched. Surface both as
1702
+ // ConditionNotMatch so callers can branch on it.
1703
+ StatusCode::PRECONDITION_FAILED
1704
+ if ctx.if_match && message.contains("resource did not exist") =>
1705
+ {
1706
+ (ErrorKind::NotFound, false)
1707
+ }
1708
+ StatusCode::PRECONDITION_FAILED | StatusCode::NOT_MODIFIED => {
1709
+ (ErrorKind::ConditionNotMatch, false)
1710
+ }
1711
+ // Allowing retry for resource locked.
1712
+ StatusCode::LOCKED => (ErrorKind::Unexpected, true),
1713
+ StatusCode::INTERNAL_SERVER_ERROR
1714
+ | StatusCode::BAD_GATEWAY
1715
+ | StatusCode::SERVICE_UNAVAILABLE
1716
+ | StatusCode::GATEWAY_TIMEOUT => (ErrorKind::Unexpected, true),
1717
+ _ => (ErrorKind::Unexpected, false),
1718
+ };
1719
+
1720
+ let mut err = Error::new(kind, message);
1721
+
1722
+ err = err.with_context("service_operation", ctx.service_operation.0);
1723
+ err = with_error_response_context(err, parts);
1724
+
1725
+ if retryable {
1726
+ err = err.set_temporary();
1727
+ }
1728
+
1729
+ err
1730
+ }
@@ -43,7 +43,10 @@ impl oio::OneShotDelete for WebdavDeleter {
43
43
  let status = resp.status();
44
44
  match status {
45
45
  StatusCode::NO_CONTENT | StatusCode::NOT_FOUND => Ok(()),
46
- _ => Err(parse_error(resp)),
46
+ _ => Err(parse_error(
47
+ ErrorContext::new(ServiceOperation("Delete")),
48
+ resp,
49
+ )),
47
50
  }
48
51
  }
49
52
  }
@@ -66,7 +66,10 @@ impl oio::PageList for WebdavLister {
66
66
  ctx.done = true;
67
67
  return Ok(());
68
68
  } else {
69
- return Err(parse_error(resp));
69
+ return Err(parse_error(
70
+ ErrorContext::new(ServiceOperation("Propfind")),
71
+ resp,
72
+ ));
70
73
  };
71
74
 
72
75
  let result: Multistatus = deserialize_multistatus(&bs.to_bytes())?;
@@ -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::oio;
@@ -67,7 +67,11 @@ impl oio::StreamRead for WebdavReader {
67
67
  _ => {
68
68
  let (part, mut body) = resp.into_parts();
69
69
  let buf = body.to_buffer().await?;
70
- return Err(parse_error(Response::from_parts(part, buf)));
70
+ return Err(parse_error(
71
+ ErrorContext::new(ServiceOperation("Get"))
72
+ .with_if_match(args.if_match().is_some()),
73
+ Response::from_parts(part, buf),
74
+ ));
71
75
  }
72
76
  };
73
77
 
@@ -43,17 +43,17 @@ impl WebdavWriter {
43
43
  }
44
44
 
45
45
  fn parse_metadata(headers: &http::HeaderMap) -> Result<Metadata> {
46
- let mut metadata = Metadata::default();
46
+ let mut metadata = MetadataBuilder::unknown();
47
47
 
48
48
  if let Some(etag) = parse_etag(headers)? {
49
- metadata.set_etag(etag);
49
+ metadata.etag(etag);
50
50
  }
51
51
 
52
52
  if let Some(last_modified) = parse_last_modified(headers)? {
53
- metadata.set_last_modified(last_modified);
53
+ metadata.last_modified(last_modified);
54
54
  }
55
55
 
56
- Ok(metadata)
56
+ Ok(metadata.build())
57
57
  }
58
58
  }
59
59
 
@@ -79,9 +79,13 @@ impl oio::OneShotWrite for WebdavWriter {
79
79
 
80
80
  // Set user metadata using PROPPATCH if provided
81
81
  if let Some(user_metadata) = self.op.user_metadata() {
82
+ let user_metadata = user_metadata
83
+ .into_iter()
84
+ .map(|(key, value)| (key.to_owned(), value.to_owned()))
85
+ .collect();
82
86
  let proppatch_resp = self
83
87
  .core
84
- .webdav_proppatch(&self.ctx, &self.path, user_metadata)
88
+ .webdav_proppatch(&self.ctx, &self.path, &user_metadata)
85
89
  .await?;
86
90
 
87
91
  let proppatch_status = proppatch_resp.status();
@@ -92,13 +96,19 @@ impl oio::OneShotWrite for WebdavWriter {
92
96
  let xml = String::from_utf8_lossy(&body);
93
97
  check_proppatch_response(&xml)?;
94
98
  } else if !proppatch_status.is_success() {
95
- return Err(parse_error(proppatch_resp));
99
+ return Err(parse_error(
100
+ ErrorContext::new(ServiceOperation("Proppatch")),
101
+ proppatch_resp,
102
+ ));
96
103
  }
97
104
  }
98
105
 
99
106
  Ok(metadata)
100
107
  }
101
- _ => Err(parse_error(resp)),
108
+ _ => Err(parse_error(
109
+ ErrorContext::new(ServiceOperation("Put")),
110
+ resp,
111
+ )),
102
112
  }
103
113
  }
104
114
  }
@@ -33,11 +33,11 @@ all-features = true
33
33
 
34
34
  [dependencies]
35
35
  anyhow = { version = "1.0.100", features = ["std"] }
36
+ asyncband = { workspace = true }
36
37
  bytes = { workspace = true }
37
38
  http = { workspace = true }
38
39
  log = { workspace = true }
39
- mea = { workspace = true }
40
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
40
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
41
41
  serde = { workspace = true, features = ["derive"] }
42
42
  serde_json = { workspace = true }
43
43
  uuid = { workspace = true, features = ["serde", "v4"] }
@@ -18,15 +18,15 @@
18
18
  use std::fmt::Debug;
19
19
  use std::sync::Arc;
20
20
 
21
+ use asyncband::once::OnceCell;
21
22
  use bytes::Buf;
22
23
  use http::StatusCode;
23
24
  use log::debug;
24
- use mea::once::OnceCell;
25
25
 
26
26
  use super::WEBHDFS_SCHEME;
27
27
  use super::config::WebhdfsConfig;
28
- use super::core::WebhdfsCore;
29
28
  use super::core::parse_error;
29
+ use super::core::{ErrorContext, WebhdfsCore};
30
30
  use super::deleter::WebhdfsDeleter;
31
31
  use super::lister::WebhdfsLister;
32
32
  use super::message::BooleanResp;
@@ -229,7 +229,12 @@ impl WebhdfsBackend {
229
229
  StatusCode::NOT_FOUND => {
230
230
  self.create_dir(ctx, "/", OpCreateDir::new()).await?;
231
231
  }
232
- _ => return Err(parse_error(resp)),
232
+ _ => {
233
+ return Err(parse_error(
234
+ ErrorContext::new(ServiceOperation("GetFileStatus")),
235
+ resp,
236
+ ));
237
+ }
233
238
  }
234
239
  Ok(())
235
240
  }
@@ -241,6 +246,7 @@ impl Service for WebhdfsBackend {
241
246
  type Lister = oio::PageLister<WebhdfsLister>;
242
247
  type Deleter = oio::OneShotDeleter<WebhdfsDeleter>;
243
248
  type Copier = ();
249
+ type Composer = ();
244
250
 
245
251
  fn info(&self) -> ServiceInfo {
246
252
  self.core.info.clone()
@@ -280,7 +286,10 @@ impl Service for WebhdfsBackend {
280
286
  ))
281
287
  }
282
288
  }
283
- _ => Err(parse_error(resp)),
289
+ _ => Err(parse_error(
290
+ ErrorContext::new(ServiceOperation("Mkdirs")),
291
+ resp,
292
+ )),
284
293
  }
285
294
  }
286
295
 
@@ -302,18 +311,23 @@ impl Service for WebhdfsBackend {
302
311
  .file_status;
303
312
 
304
313
  let meta = match file_status.ty {
305
- FileStatusType::Directory => Metadata::new(EntryMode::DIR),
306
- FileStatusType::File => Metadata::new(EntryMode::FILE)
307
- .with_content_length(file_status.length)
308
- .with_last_modified(Timestamp::from_millisecond(
314
+ FileStatusType::Directory => MetadataBuilder::dir().build(),
315
+ FileStatusType::File => {
316
+ let mut metadata = MetadataBuilder::file(file_status.length);
317
+ metadata.last_modified(Timestamp::from_millisecond(
309
318
  file_status.modification_time,
310
- )?),
319
+ )?);
320
+ metadata.build()
321
+ }
311
322
  };
312
323
 
313
324
  Ok(RpStat::new(meta))
314
325
  }
315
326
 
316
- _ => Err(parse_error(resp)),
327
+ _ => Err(parse_error(
328
+ ErrorContext::new(ServiceOperation("GetFileStatus")),
329
+ resp,
330
+ )),
317
331
  }
318
332
  }
319
333
  fn read(&self, ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
@@ -388,7 +402,6 @@ impl Service for WebhdfsBackend {
388
402
  _from: &str,
389
403
  _to: &str,
390
404
  _args: OpCopy,
391
- _opts: OpCopier,
392
405
  ) -> Result<Self::Copier> {
393
406
  Err(Error::new(
394
407
  ErrorKind::Unsupported,