diff --git a/bindings/zig/test/bdd.zig b/bindings/zig/test/bdd.zig index c998454c9b8b..79748fa3b196 100644 --- a/bindings/zig/test/bdd.zig +++ b/bindings/zig/test/bdd.zig @@ -62,16 +62,16 @@ test "Opendal BDD test" { .len = std.mem.len(testkit.content), }; const code = opendal.c.opendal_operator_blocking_write(testkit.p, testkit.path, data); - try testing.expectEqual(code, @enumToInt(Code.OK)); + try testing.expectEqual(code, @intFromEnum(Code.OK)); // The blocking file "test" should exist var e: opendal.c.opendal_result_is_exist = opendal.c.opendal_operator_is_exist(testkit.p, testkit.path); - try testing.expectEqual(e.code, @enumToInt(Code.OK)); + try testing.expectEqual(e.code, @intFromEnum(Code.OK)); try testing.expect(e.is_exist); // The blocking file "test" entry mode must be file var s: opendal.c.opendal_result_stat = opendal.c.opendal_operator_stat(testkit.p, testkit.path); - try testing.expectEqual(s.code, @enumToInt(Code.OK)); + try testing.expectEqual(s.code, @intFromEnum(Code.OK)); var meta: [*c]opendal.c.opendal_metadata = s.meta; try testing.expect(opendal.c.opendal_metadata_is_file(meta)); @@ -82,7 +82,7 @@ test "Opendal BDD test" { // The blocking file "test" must have content "Hello, World!" var r: opendal.c.opendal_result_read = opendal.c.opendal_operator_blocking_read(testkit.p, testkit.path); defer opendal.c.opendal_bytes_free(r.data); - try testing.expect(r.code == @enumToInt(Code.OK)); + try testing.expect(r.code == @intFromEnum(Code.OK)); try testing.expectEqual(std.mem.len(testkit.content), r.data.*.len); var count: usize = 0; diff --git a/core/src/raw/adapters/typed_kv/backend.rs b/core/src/raw/adapters/typed_kv/backend.rs index 126a731b2f20..84afa5ca457f 100644 --- a/core/src/raw/adapters/typed_kv/backend.rs +++ b/core/src/raw/adapters/typed_kv/backend.rs @@ -221,6 +221,58 @@ impl Accessor for Backend { Ok((RpList::default(), pager)) } + + async fn rename(&self, from: &str, to: &str, _: OpRename) -> Result { + match self.copy(from, to, OpCopy {}).await { + Ok(_) => { + let from = build_abs_path(&self.root, from); + self.kv.delete(&from).await?; + Ok(RpRename::default()) + } + Err(e) => Err(e), + } + } + + fn blocking_rename(&self, from: &str, to: &str, _: OpRename) -> Result { + match self.blocking_copy(from, to, OpCopy {}) { + Ok(_) => { + let from = build_abs_path(&self.root, from); + self.kv.blocking_delete(&from)?; + Ok(RpRename::default()) + } + Err(e) => Err(e), + } + } + + async fn copy(&self, from: &str, to: &str, _: OpCopy) -> Result { + let from = build_abs_path(&self.root, from); + let to = build_abs_path(&self.root, to); + + let bs = match self.kv.get(&from).await? { + // TODO: we can reuse the metadata in value to build content range. + Some(bs) => bs, + None => return Err(Error::new(ErrorKind::NotFound, "kv doesn't have this path")), + }; + + self.kv.set(&to, bs).await?; + + Ok(RpCopy::default()) + } + + fn blocking_copy(&self, from: &str, to: &str, _: OpCopy) -> Result { + let from = build_abs_path(&self.root, from); + let to = build_abs_path(&self.root, to); + + let bs = match self.kv.blocking_get(&from)? { + // TODO: we can reuse the metadata in value to build content range. + Some(bs) => bs, + None => return Err(Error::new(ErrorKind::NotFound, "kv doesn't have this path")), + }; + + self.kv.blocking_set(&to, bs)?; + + Ok(RpCopy::default()) + } } impl Backend