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
@@ -245,6 +245,7 @@ impl Service for FoyerBackend {
245
245
  type Lister = ();
246
246
  type Deleter = oio::OneShotDeleter<FoyerDeleter>;
247
247
  type Copier = ();
248
+ type Composer = ();
248
249
 
249
250
  fn info(&self) -> ServiceInfo {
250
251
  self.info.clone()
@@ -270,12 +271,13 @@ impl Service for FoyerBackend {
270
271
  let p = build_abs_path(&self.root, path);
271
272
 
272
273
  if p == build_abs_path(&self.root, "") {
273
- Ok(RpStat::new(Metadata::new(EntryMode::DIR)))
274
+ Ok(RpStat::new(MetadataBuilder::dir().build()))
274
275
  } else {
275
276
  match self.core.get(&p).await? {
276
- Some(bs) => Ok(RpStat::new(
277
- Metadata::new(EntryMode::FILE).with_content_length(bs.len() as u64),
278
- )),
277
+ Some(bs) => Ok(RpStat::new({
278
+ let metadata = MetadataBuilder::file(bs.len() as u64);
279
+ metadata.build()
280
+ })),
279
281
  None => Err(Error::new(ErrorKind::NotFound, "key not found in foyer")),
280
282
  }
281
283
  }
@@ -325,7 +327,6 @@ impl Service for FoyerBackend {
325
327
  _from: &str,
326
328
  _to: &str,
327
329
  _args: OpCopy,
328
- _opts: OpCopier,
329
330
  ) -> Result<Self::Copier> {
330
331
  Err(Error::new(
331
332
  ErrorKind::Unsupported,
@@ -48,7 +48,10 @@ impl oio::StreamRead for FoyerReader {
48
48
 
49
49
  let buffer = buffer.slice(range.to_content_range(buffer.len())?);
50
50
 
51
- let metadata = Metadata::new(EntryMode::FILE).with_content_length(content_length);
51
+ let metadata = {
52
+ let metadata = MetadataBuilder::file(content_length);
53
+ metadata.build()
54
+ };
52
55
  Ok((
53
56
  RpRead::new(metadata),
54
57
  Box::new(buffer) as Box<dyn oio::ReadStreamDyn>,
@@ -49,8 +49,12 @@ impl oio::Write for FoyerWriter {
49
49
  let length = buf.len() as u64;
50
50
  self.core.insert(&self.path, buf).await?;
51
51
 
52
- let meta = Metadata::new(EntryMode::from_path(&self.path)).with_content_length(length);
53
- Ok(meta)
52
+ let metadata = if self.path.ends_with('/') {
53
+ MetadataBuilder::dir()
54
+ } else {
55
+ MetadataBuilder::file(length)
56
+ };
57
+ Ok(metadata.build())
54
58
  }
55
59
 
56
60
  async fn abort(&mut self) -> Result<()> {
@@ -34,7 +34,7 @@ all-features = true
34
34
  [dependencies]
35
35
  bytes = { workspace = true }
36
36
  log = { workspace = true }
37
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false, features = [
37
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false, features = [
38
38
  "internal-tokio-rt",
39
39
  ] }
40
40
  serde = { workspace = true, features = ["derive"] }
@@ -180,6 +180,7 @@ impl Service for FsBackend {
180
180
  type Lister = FsLazyLister;
181
181
  type Deleter = oio::OneShotDeleter<FsDeleter>;
182
182
  type Copier = oio::OneShotCopier;
183
+ type Composer = ();
183
184
 
184
185
  fn info(&self) -> ServiceInfo {
185
186
  self.core.info.clone()
@@ -234,14 +235,14 @@ impl Service for FsBackend {
234
235
  from: &str,
235
236
  to: &str,
236
237
  _args: OpCopy,
237
- _opts: OpCopier,
238
238
  ) -> Result<Self::Copier> {
239
239
  let core = self.core.clone();
240
240
  let from = from.to_string();
241
241
  let to = to.to_string();
242
242
  Ok(oio::OneShotCopier::new(async move {
243
- core.fs_copy(&from, &to).await?;
244
- Ok(Metadata::default())
243
+ let size = core.fs_copy(&from, &to).await?;
244
+ let metadata = MetadataBuilder::file(size);
245
+ Ok(metadata.build())
245
246
  }))
246
247
  }
247
248
 
@@ -110,22 +110,25 @@ impl FsCore {
110
110
  } else {
111
111
  EntryMode::Unknown
112
112
  };
113
- let mut m = Metadata::new(mode)
114
- .with_content_length(meta.len())
115
- .with_last_modified(Timestamp::try_from(
116
- meta.modified().map_err(new_std_io_error)?,
117
- )?);
113
+ let mut m = match mode {
114
+ EntryMode::FILE => MetadataBuilder::file(meta.len()),
115
+ EntryMode::DIR => MetadataBuilder::dir(),
116
+ EntryMode::Unknown => MetadataBuilder::unknown(),
117
+ };
118
+ m.last_modified(Timestamp::try_from(
119
+ meta.modified().map_err(new_std_io_error)?,
120
+ )?);
118
121
 
119
122
  // Read user metadata from xattr on Unix systems
120
123
  #[cfg(unix)]
121
124
  {
122
125
  let user_metadata = Self::get_user_metadata(&p)?;
123
126
  if !user_metadata.is_empty() {
124
- m = m.with_user_metadata(user_metadata);
127
+ m.user_metadata(user_metadata);
125
128
  }
126
129
  }
127
130
 
128
- Ok(m)
131
+ Ok(m.build())
129
132
  }
130
133
 
131
134
  pub async fn fs_open(&self, path: &str) -> Result<File> {
@@ -158,7 +161,10 @@ impl FsCore {
158
161
  open_options.truncate(true);
159
162
  }
160
163
 
161
- let f = open_options.open(path).await.map_err(parse_error)?;
164
+ let f = open_options
165
+ .open(path)
166
+ .await
167
+ .map_err(|err| parse_error(ErrorContext::new(ServiceOperation("OpenForWrite")), err))?;
162
168
 
163
169
  Ok(f)
164
170
  }
@@ -188,7 +194,12 @@ impl FsCore {
188
194
  open_options.write(true);
189
195
  open_options.truncate(true);
190
196
 
191
- let f = open_options.open(&tmp_path).await.map_err(parse_error)?;
197
+ let f = open_options.open(&tmp_path).await.map_err(|err| {
198
+ parse_error(
199
+ ErrorContext::new(ServiceOperation("OpenTemporaryFile")),
200
+ err,
201
+ )
202
+ })?;
192
203
 
193
204
  Ok((f, Some(tmp_path)))
194
205
  }
@@ -215,7 +226,7 @@ impl FsCore {
215
226
  }
216
227
  }
217
228
 
218
- pub async fn fs_copy(&self, from: &str, to: &str) -> Result<()> {
229
+ pub async fn fs_copy(&self, from: &str, to: &str) -> Result<u64> {
219
230
  let from = self.root_join(from)?;
220
231
  // try to get the metadata of the source file to ensure it exists
221
232
  tokio::fs::metadata(&from).await.map_err(new_std_io_error)?;
@@ -224,7 +235,7 @@ impl FsCore {
224
235
  .ensure_write_abs_path(&self.root, to.trim_end_matches('/'))
225
236
  .await?;
226
237
 
227
- tokio::fs::copy(&from, &to)
238
+ let size = tokio::fs::copy(&from, &to)
228
239
  .await
229
240
  .map_err(new_std_io_error)?;
230
241
 
@@ -238,7 +249,7 @@ impl FsCore {
238
249
  }
239
250
  }
240
251
 
241
- Ok(())
252
+ Ok(size)
242
253
  }
243
254
 
244
255
  pub async fn fs_rename(&self, from: &str, to: &str) -> Result<()> {
@@ -315,24 +326,31 @@ impl FsCore {
315
326
  #[cfg(unix)]
316
327
  const XATTR_USER_PREFIX: &str = "user.";
317
328
 
318
- mod error {
319
- use opendal_core::raw::*;
320
- use opendal_core::*;
329
+ /// Context needed to classify an error from this service.
330
+ #[derive(Clone, Copy, Debug)]
331
+ pub(crate) struct ErrorContext {
332
+ service_operation: ServiceOperation,
333
+ }
321
334
 
322
- /// Parse error response into Error.
323
- pub(crate) fn parse_error(e: std::io::Error) -> Error {
324
- match e.kind() {
325
- std::io::ErrorKind::AlreadyExists => Error::new(
326
- ErrorKind::ConditionNotMatch,
327
- "The file already exists in the filesystem",
328
- )
329
- .set_source(e),
330
- _ => new_std_io_error(e),
331
- }
335
+ impl ErrorContext {
336
+ pub(crate) const fn new(service_operation: ServiceOperation) -> Self {
337
+ Self { service_operation }
332
338
  }
333
339
  }
334
340
 
335
- pub(super) use error::*;
341
+ /// Parse an error using its service operation context.
342
+ pub(crate) fn parse_error(ctx: ErrorContext, err: std::io::Error) -> Error {
343
+ let err = match err.kind() {
344
+ std::io::ErrorKind::AlreadyExists => Error::new(
345
+ ErrorKind::ConditionNotMatch,
346
+ "The file already exists in the filesystem",
347
+ )
348
+ .set_source(err),
349
+ _ => new_std_io_error(err),
350
+ };
351
+
352
+ err.with_context("service_operation", ctx.service_operation.0)
353
+ }
336
354
 
337
355
  #[cfg(test)]
338
356
  mod tests {
@@ -19,7 +19,7 @@ use std::path::Path;
19
19
  use std::path::PathBuf;
20
20
 
21
21
  use opendal_core::EntryMode;
22
- use opendal_core::Metadata;
22
+ use opendal_core::MetadataBuilder;
23
23
  use opendal_core::Result;
24
24
  use opendal_core::raw::*;
25
25
 
@@ -51,7 +51,7 @@ impl oio::List for FsLister<tokio::fs::ReadDir> {
51
51
  loop {
52
52
  // since list should return path itself, we return it first
53
53
  if let Some(path) = self.current_path.take() {
54
- let e = oio::Entry::new(path.as_str(), Metadata::new(EntryMode::DIR));
54
+ let e = oio::Entry::new(path.as_str(), MetadataBuilder::dir().build());
55
55
  return Ok(Some(e));
56
56
  }
57
57
 
@@ -106,11 +106,14 @@ impl oio::List for FsLister<tokio::fs::ReadDir> {
106
106
  }
107
107
  Err(e) => return Err(new_std_io_error(e)),
108
108
  };
109
- let metadata = Metadata::new(mode)
110
- .with_content_length(de_metadata.len())
111
- .with_last_modified(Timestamp::try_from(last_modified)?);
109
+ let mut metadata = match mode {
110
+ EntryMode::FILE => MetadataBuilder::file(de_metadata.len()),
111
+ EntryMode::DIR => MetadataBuilder::dir(),
112
+ EntryMode::Unknown => MetadataBuilder::unknown(),
113
+ };
114
+ metadata.last_modified(Timestamp::try_from(last_modified)?);
112
115
 
113
- return Ok(Some(oio::Entry::new(path, metadata)));
116
+ return Ok(Some(oio::Entry::new(path, metadata.build())));
114
117
  }
115
118
  }
116
119
  }
@@ -46,7 +46,12 @@ impl FsWriter {
46
46
 
47
47
  // Store user metadata for later use on Unix systems.
48
48
  #[cfg(unix)]
49
- let user_metadata = op.user_metadata().cloned();
49
+ let user_metadata = op.user_metadata().map(|metadata| {
50
+ metadata
51
+ .into_iter()
52
+ .map(|(key, value)| (key.to_owned(), value.to_owned()))
53
+ .collect()
54
+ });
50
55
 
51
56
  // Quick path while atomic_write_dir is not set.
52
57
  if core.atomic_write_dir.is_none() {
@@ -123,12 +128,11 @@ impl oio::Write for FsWriter {
123
128
  }
124
129
 
125
130
  let file_meta = self.f.metadata().await.map_err(new_std_io_error)?;
126
- let meta = Metadata::new(EntryMode::FILE)
127
- .with_content_length(file_meta.len())
128
- .with_last_modified(Timestamp::try_from(
129
- file_meta.modified().map_err(new_std_io_error)?,
130
- )?);
131
- Ok(meta)
131
+ let mut meta = MetadataBuilder::file(file_meta.len());
132
+ meta.last_modified(Timestamp::try_from(
133
+ file_meta.modified().map_err(new_std_io_error)?,
134
+ )?);
135
+ Ok(meta.build())
132
136
  }
133
137
 
134
138
  async fn abort(&mut self) -> Result<()> {
@@ -205,12 +209,15 @@ impl oio::PositionWrite for FsWriter {
205
209
  } else {
206
210
  EntryMode::Unknown
207
211
  };
208
- let meta = Metadata::new(mode)
209
- .with_content_length(file_meta.len())
210
- .with_last_modified(Timestamp::try_from(
211
- file_meta.modified().map_err(new_std_io_error)?,
212
- )?);
213
- Ok(meta)
212
+ let mut meta = match mode {
213
+ EntryMode::FILE => MetadataBuilder::file(file_meta.len()),
214
+ EntryMode::DIR => MetadataBuilder::dir(),
215
+ EntryMode::Unknown => MetadataBuilder::unknown(),
216
+ };
217
+ meta.last_modified(Timestamp::try_from(
218
+ file_meta.modified().map_err(new_std_io_error)?,
219
+ )?);
220
+ Ok(meta.build())
214
221
  }
215
222
 
216
223
  async fn abort(&self) -> Result<()> {
@@ -34,17 +34,15 @@ all-features = true
34
34
  [dependencies]
35
35
  bytes = { workspace = true }
36
36
  fastpool = "1.0.2"
37
- futures = { workspace = true, features = ["std", "async-await"] }
38
- futures-rustls = "0.26.0"
39
37
  http = { workspace = true }
40
38
  log = { workspace = true }
41
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false }
39
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false }
42
40
  rustls-native-certs = "0.8"
43
41
  serde = { workspace = true, features = ["derive"] }
44
- suppaftp = { version = "8.0.3", default-features = false, features = [
45
- "async-std-rustls-ring",
42
+ suppaftp = { version = "10.0.2", default-features = false, features = [
43
+ "tokio-rustls-ring",
46
44
  ] }
47
- tokio = { workspace = true, features = ["macros", "time"] }
45
+ tokio = { workspace = true, features = ["io-util", "macros", "time"] }
48
46
 
49
47
  [dev-dependencies]
50
48
  tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
@@ -162,6 +162,7 @@ impl Builder for FtpBuilder {
162
162
 
163
163
  let manager = Manager {
164
164
  endpoint: endpoint.clone(),
165
+ host: host.to_string(),
165
166
  root: root.clone(),
166
167
  user: user.clone(),
167
168
  password: password.clone(),
@@ -190,6 +191,7 @@ impl Service for FtpBackend {
190
191
  type Lister = FtpLazyLister;
191
192
  type Deleter = oio::OneShotDeleter<FtpDeleter>;
192
193
  type Copier = ();
194
+ type Composer = ();
193
195
 
194
196
  fn info(&self) -> ServiceInfo {
195
197
  self.core.info()
@@ -240,11 +242,14 @@ impl Service for FtpBackend {
240
242
  EntryMode::Unknown
241
243
  };
242
244
 
243
- let mut meta = Metadata::new(mode);
244
- meta.set_content_length(file.size() as u64);
245
- meta.set_last_modified(Timestamp::try_from(file.modified())?);
245
+ let mut meta = match mode {
246
+ EntryMode::FILE => MetadataBuilder::file(file.size() as u64),
247
+ EntryMode::DIR => MetadataBuilder::dir(),
248
+ EntryMode::Unknown => MetadataBuilder::unknown(),
249
+ };
250
+ meta.last_modified(Timestamp::try_from(file.modified())?);
246
251
 
247
- Ok(RpStat::new(meta))
252
+ Ok(RpStat::new(meta.build()))
248
253
  }
249
254
  fn read(&self, _ctx: &OperationContext, path: &str, args: OpRead) -> Result<Self::Reader> {
250
255
  let output: oio::StreamReader<FtpReader> = {
@@ -279,7 +284,6 @@ impl Service for FtpBackend {
279
284
  _from: &str,
280
285
  _to: &str,
281
286
  _args: OpCopy,
282
- _opts: OpCopier,
283
287
  ) -> Result<Self::Copier> {
284
288
  Err(Error::new(
285
289
  ErrorKind::Unsupported,
@@ -16,16 +16,17 @@
16
16
  // under the License.
17
17
 
18
18
  use std::sync::Arc;
19
+ use std::time::Duration;
19
20
 
20
21
  use fastpool::{ManageObject, ObjectStatus, bounded};
21
- use futures_rustls::TlsConnector;
22
- use futures_rustls::rustls::ClientConfig;
23
- use futures_rustls::rustls::RootCertStore;
24
22
  use suppaftp::FtpError;
25
23
  use suppaftp::Status;
26
- use suppaftp::async_std::AsyncRustlsConnector;
27
- use suppaftp::async_std::AsyncRustlsFtpStream;
28
- use suppaftp::async_std::ImplAsyncFtpStream;
24
+ use suppaftp::tokio::AsyncRustlsConnector;
25
+ use suppaftp::tokio::AsyncRustlsFtpStream;
26
+ use suppaftp::tokio::ImplAsyncFtpStream;
27
+ use suppaftp::tokio_rustls::TlsConnector;
28
+ use suppaftp::tokio_rustls::rustls::ClientConfig;
29
+ use suppaftp::tokio_rustls::rustls::RootCertStore;
29
30
  use suppaftp::types::FileType;
30
31
 
31
32
  use opendal_core::raw::*;
@@ -73,6 +74,7 @@ impl FtpCore {
73
74
  #[derive(Clone)]
74
75
  pub struct Manager {
75
76
  pub endpoint: String,
77
+ pub host: String,
76
78
  pub root: String,
77
79
  pub user: String,
78
80
  pub password: String,
@@ -100,7 +102,7 @@ impl ManageObject for Manager {
100
102
  stream
101
103
  .into_secure(
102
104
  AsyncRustlsConnector::from(TlsConnector::from(Arc::new(cfg))),
103
- &self.endpoint,
105
+ &self.host,
104
106
  )
105
107
  .await?
106
108
  } else {
@@ -50,21 +50,20 @@ impl oio::List for FtpLister {
50
50
  let path = self.path.to_string() + de.name();
51
51
 
52
52
  let mut meta = if de.is_file() {
53
- Metadata::new(EntryMode::FILE)
53
+ MetadataBuilder::file(de.size() as u64)
54
54
  } else if de.is_directory() {
55
- Metadata::new(EntryMode::DIR)
55
+ MetadataBuilder::dir()
56
56
  } else {
57
- Metadata::new(EntryMode::Unknown)
57
+ MetadataBuilder::unknown()
58
58
  };
59
- meta.set_content_length(de.size() as u64);
60
- meta.set_last_modified(Timestamp::try_from(de.modified())?);
59
+ meta.last_modified(Timestamp::try_from(de.modified())?);
61
60
 
62
61
  let entry = if de.is_file() {
63
- oio::Entry::new(&path, meta)
62
+ oio::Entry::new(&path, meta.build())
64
63
  } else if de.is_directory() {
65
- oio::Entry::new(&format!("{}/", path), meta)
64
+ oio::Entry::new(&format!("{}/", path), meta.build())
66
65
  } else {
67
- oio::Entry::new(&path, meta)
66
+ oio::Entry::new(&path, meta.build())
68
67
  };
69
68
 
70
69
  Ok(Some(entry))
@@ -23,14 +23,14 @@ use super::lister::FtpLister;
23
23
  use super::writer::FtpWriter;
24
24
  use bytes::BytesMut;
25
25
  use fastpool::bounded;
26
- use futures::AsyncRead;
27
- use futures::AsyncReadExt;
28
26
  use opendal_core::raw::*;
29
27
  use opendal_core::*;
30
28
  use std::sync::Arc;
31
29
  use suppaftp::FtpError;
32
30
  use suppaftp::Status;
33
31
  use suppaftp::types::Response;
32
+ use tokio::io::AsyncRead;
33
+ use tokio::io::AsyncReadExt;
34
34
 
35
35
  pub struct FtpReadStream {
36
36
  /// Keep the connection alive while data stream is alive.
@@ -164,7 +164,7 @@ impl oio::Write for FtpLazyWriter {
164
164
  async fn close(&mut self) -> Result<Metadata> {
165
165
  match &mut self.inner {
166
166
  Some(w) => w.close().await,
167
- None => Ok(Metadata::default()),
167
+ None => Ok(MetadataBuilder::unknown().build()),
168
168
  }
169
169
  }
170
170
 
@@ -17,8 +17,8 @@
17
17
 
18
18
  use bytes::Buf;
19
19
  use fastpool::bounded;
20
- use futures::AsyncWrite;
21
- use futures::AsyncWriteExt;
20
+ use tokio::io::AsyncWrite;
21
+ use tokio::io::AsyncWriteExt;
22
22
 
23
23
  use super::core::Manager;
24
24
  use super::core::format_ftp_error;
@@ -110,7 +110,7 @@ impl oio::Write for FtpWriter {
110
110
  }
111
111
  }
112
112
 
113
- Ok(Metadata::default())
113
+ Ok(MetadataBuilder::unknown().build())
114
114
  }
115
115
 
116
116
  async fn abort(&mut self) -> Result<()> {
@@ -36,7 +36,7 @@ async-trait = "0.1"
36
36
  bytes = { workspace = true }
37
37
  http = { workspace = true }
38
38
  log = { workspace = true }
39
- opendal-core = { path = "../../core", version = "0.58.1", default-features = false, features = [
39
+ opendal-core = { path = "../../core", version = "0.59.0", default-features = false, features = [
40
40
  "reqsign",
41
41
  ] }
42
42
  percent-encoding = "2.3"
@@ -47,7 +47,9 @@ reqsign-google = { version = "3.0.3", default-features = false }
47
47
  serde = { workspace = true, features = ["derive"] }
48
48
  serde_json = { workspace = true }
49
49
  tokio = { workspace = true, features = ["rt"] }
50
+ uuid = { workspace = true, features = ["v4"] }
50
51
 
51
52
  [dev-dependencies]
53
+ futures = { workspace = true }
52
54
  serde_json = { workspace = true }
53
- tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
55
+ tokio = { workspace = true, features = ["macros", "rt-multi-thread", "sync"] }