This is an automated email from the ASF dual-hosted git repository.

tison pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-opendal.git


The following commit(s) were added to refs/heads/main by this push:
     new 016f3aed8 refactor(bindings/zig): add errors handler and module test 
(#2381)
016f3aed8 is described below

commit 016f3aed877b235269e2a194f96069bc99d12709
Author: Matheus C. França <[email protected]>
AuthorDate: Wed May 31 11:14:52 2023 -0300

    refactor(bindings/zig): add errors handler and module test (#2381)
---
 bindings/zig/build.zig                         |  11 +-
 bindings/zig/src/opendal.zig                   | 157 ++++++++++++++-----------
 bindings/zig/{src/opendal.zig => test/bdd.zig} |  48 ++++----
 3 files changed, 123 insertions(+), 93 deletions(-)

diff --git a/bindings/zig/build.zig b/bindings/zig/build.zig
index 4e26a08af..55304529e 100644
--- a/bindings/zig/build.zig
+++ b/bindings/zig/build.zig
@@ -39,12 +39,13 @@ pub fn build(b: *std.Build) void {
     // but does not run it.
     const unit_tests = b.addTest(.{
         .root_source_file = .{
-            .path = "src/opendal.zig",
+            .path = "test/bdd.zig",
         },
         .target = target,
         .optimize = optimize,
     });
     unit_tests.addIncludePath("../c/include");
+    unit_tests.addModule("opendal", module(b));
     if (optimize == .Debug) {
         unit_tests.addLibraryPath("../../target/debug");
     } else {
@@ -70,3 +71,11 @@ fn buildLibOpenDAL(b: *std.Build) *std.Build.Step.Run {
         "build",
     });
 }
+
+pub fn module(b: *std.Build) *std.Build.Module {
+    return b.createModule(.{
+        .source_file = .{
+            .path = "src/opendal.zig",
+        },
+    });
+}
diff --git a/bindings/zig/src/opendal.zig b/bindings/zig/src/opendal.zig
index 2da87c423..93c504742 100644
--- a/bindings/zig/src/opendal.zig
+++ b/bindings/zig/src/opendal.zig
@@ -15,79 +15,96 @@
 // specific language governing permissions and limitations
 // under the License.
 
-pub const opendal = @cImport(@cInclude("opendal.h"));
-
-const std = @import("std");
-const testing = std.testing;
-
-test "Opendal BDD test" {
-    const c_str = [*:0]const u8; // define a type for 'const char*' in C
-
-    const OpendalBDDTest = struct {
-        p: opendal.opendal_operator_ptr,
-        scheme: c_str,
-        path: c_str,
-        content: c_str,
-
-        pub fn init() Self {
-            var self: Self = undefined;
-            self.scheme = "memory";
-            self.path = "test";
-            self.content = "Hello, World!";
-
-            var options: opendal.opendal_operator_options = 
opendal.opendal_operator_options_new();
-            defer opendal.opendal_operator_options_free(&options);
-            opendal.opendal_operator_options_set(&options, "root", "/myroot");
-
-            // Given A new OpenDAL Blocking Operator
-            self.p = opendal.opendal_operator_new(self.scheme, &options);
-            std.debug.assert(self.p.ptr != null);
-
-            return self;
-        }
-
-        pub fn deinit(self: *Self) void {
-            opendal.opendal_operator_free(&self.p);
-        }
-
-        const Self = @This();
+pub const c = @cImport(@cInclude("opendal.h"));
+
+// Zig code get values C code
+pub const Code = enum(c.opendal_code) {
+    OK = c.OPENDAL_OK,
+    ERROR = c.OPENDAL_ERROR,
+    UNEXPECTED = c.OPENDAL_UNEXPECTED,
+    UNSUPPORTED = c.OPENDAL_UNSUPPORTED,
+    CONFIG_INVALID = c.OPENDAL_CONFIG_INVALID,
+    NOT_FOUND = c.OPENDAL_NOT_FOUND,
+    PERMISSION_DENIED = c.OPENDAL_PERMISSION_DENIED,
+    IS_A_DIRECTORY = c.OPENDAL_IS_A_DIRECTORY,
+    NOT_A_DIRECTORY = c.OPENDAL_NOT_A_DIRECTORY,
+    ALREADY_EXISTS = c.OPENDAL_ALREADY_EXISTS,
+    RATE_LIMITED = c.OPENDAL_RATE_LIMITED,
+    IS_SAME_FILE = c.OPENDAL_IS_SAME_FILE,
+};
+
+pub const OpendalError = error{
+    Unexpected,
+    Unsupported,
+    ConfigInvalid,
+    NotFound,
+    PermissionDenied,
+    IsDirectory,
+    IsNotDirectory,
+    AlreadyExists,
+    RateLimited,
+    IsSameFile,
+};
+
+pub fn codeToError(code: c.opendal_code) OpendalError!c.opendal_code {
+    return switch (code) {
+        c.OPENDAL_UNEXPECTED => error.Unexpected,
+        c.OPENDAL_UNSUPPORTED => error.Unsupported,
+        c.OPENDAL_NOT_FOUND => error.NotFound,
+        c.OPENDAL_CONFIG_INVALID => error.ConfigInvalid,
+        c.OPENDAL_PERMISSION_DENIED => error.PermissionDenied,
+        c.OPENDAL_IS_A_DIRECTORY => error.IsDirectory,
+        c.OPENDAL_NOT_A_DIRECTORY => error.IsNotDirectory,
+        c.OPENDAL_ALREADY_EXISTS => error.AlreadyExists,
+        c.OPENDAL_RATE_LIMITED => error.RateLimited,
+        c.OPENDAL_IS_SAME_FILE => error.IsSameFile,
+        else => c.OPENDAL_ERROR,
     };
-
-    var testkit = OpendalBDDTest.init();
-    defer testkit.deinit();
-
-    // When Blocking write path "test" with content "Hello, World!"
-    const data: opendal.opendal_bytes = .{
-        .data = testkit.content,
-        // c_str does not have len field (.* is ptr)
-        .len = std.mem.len(testkit.content),
+}
+pub fn errorToCode(err: OpendalError) c_int {
+    return switch (err) {
+        error.Unexpected => c.OPENDAL_UNEXPECTED,
+        error.Unsupported => c.OPENDAL_UNSUPPORTED,
+        error.ConfigInvalid => c.OPENDAL_CONFIG_INVALID,
+        error.NotFound => c.OPENDAL_NOT_FOUND,
+        error.PermissionDenied => c.OPENDAL_PERMISSION_DENIED,
+        error.IsDirectory => c.OPENDAL_IS_A_DIRECTORY,
+        error.IsNotDirectory => c.OPENDAL_NOT_A_DIRECTORY,
+        error.AlreadyExists => c.OPENDAL_ALREADY_EXISTS,
+        error.RateLimited => c.OPENDAL_RATE_LIMITED,
+        error.IsSameFile => c.OPENDAL_IS_SAME_FILE,
     };
-    const code = opendal.opendal_operator_blocking_write(testkit.p, 
testkit.path, data);
-    try testing.expectEqual(code, opendal.OPENDAL_OK);
-
-    // The blocking file "test" should exist
-    var e: opendal.opendal_result_is_exist = 
opendal.opendal_operator_is_exist(testkit.p, testkit.path);
-    try testing.expectEqual(e.code, opendal.OPENDAL_OK);
-    try testing.expect(e.is_exist);
-
-    // The blocking file "test" entry mode must be file
-    var s: opendal.opendal_result_stat = 
opendal.opendal_operator_stat(testkit.p, testkit.path);
-    try testing.expectEqual(s.code, opendal.OPENDAL_OK);
-    var meta: opendal.opendal_metadata = s.meta;
-    try testing.expect(opendal.opendal_metadata_is_file(&meta));
+}
 
-    // The blocking file "test" content length must be 13
-    try testing.expectEqual(opendal.opendal_metadata_content_length(&meta), 
13);
-    defer opendal.opendal_metadata_free(&meta);
+const std = @import("std");
+const testing = std.testing;
 
-    // The blocking file "test" must have content "Hello, World!"
-    var r: opendal.opendal_result_read = 
opendal.opendal_operator_blocking_read(testkit.p, testkit.path);
-    defer opendal.opendal_bytes_free(r.data);
-    try testing.expect(r.code == opendal.OPENDAL_OK);
-    try testing.expectEqual(std.mem.len(testkit.content), r.data.*.len);
+test "Error Tests" {
+    // C code to Zig error
+    try testing.expectError(error.Unexpected, 
codeToError(c.OPENDAL_UNEXPECTED));
+    try testing.expectError(error.Unsupported, 
codeToError(c.OPENDAL_UNSUPPORTED));
+    try testing.expectError(error.ConfigInvalid, 
codeToError(c.OPENDAL_CONFIG_INVALID));
+    try testing.expectError(error.NotFound, codeToError(c.OPENDAL_NOT_FOUND));
+    try testing.expectError(error.PermissionDenied, 
codeToError(c.OPENDAL_PERMISSION_DENIED));
+    try testing.expectError(error.IsDirectory, 
codeToError(c.OPENDAL_IS_A_DIRECTORY));
+    try testing.expectError(error.IsNotDirectory, 
codeToError(c.OPENDAL_NOT_A_DIRECTORY));
+    try testing.expectError(error.AlreadyExists, 
codeToError(c.OPENDAL_ALREADY_EXISTS));
+    try testing.expectError(error.RateLimited, 
codeToError(c.OPENDAL_RATE_LIMITED));
+    try testing.expectError(error.IsSameFile, 
codeToError(c.OPENDAL_IS_SAME_FILE));
+
+    // Zig error to C code
+    try testing.expectEqual(c.OPENDAL_UNEXPECTED, 
errorToCode(error.Unexpected));
+    try testing.expectEqual(c.OPENDAL_UNSUPPORTED, 
errorToCode(error.Unsupported));
+    try testing.expectEqual(c.OPENDAL_CONFIG_INVALID, 
errorToCode(error.ConfigInvalid));
+    try testing.expectEqual(c.OPENDAL_NOT_FOUND, errorToCode(error.NotFound));
+    try testing.expectEqual(c.OPENDAL_PERMISSION_DENIED, 
errorToCode(error.PermissionDenied));
+    try testing.expectEqual(c.OPENDAL_IS_A_DIRECTORY, 
errorToCode(error.IsDirectory));
+    try testing.expectEqual(c.OPENDAL_NOT_A_DIRECTORY, 
errorToCode(error.IsNotDirectory));
+    try testing.expectEqual(c.OPENDAL_ALREADY_EXISTS, 
errorToCode(error.AlreadyExists));
+    try testing.expectEqual(c.OPENDAL_RATE_LIMITED, 
errorToCode(error.RateLimited));
+    try testing.expectEqual(c.OPENDAL_IS_SAME_FILE, 
errorToCode(error.IsSameFile));
+}
 
-    var count: usize = 0;
-    while (count < r.data.*.len) : (count += 1) {
-        try testing.expectEqual(testkit.content[count], r.data.*.data[count]);
-    }
+test "Semantic Analyzer" {
+    testing.refAllDecls(@This());
 }
diff --git a/bindings/zig/src/opendal.zig b/bindings/zig/test/bdd.zig
similarity index 59%
copy from bindings/zig/src/opendal.zig
copy to bindings/zig/test/bdd.zig
index 2da87c423..04451f784 100644
--- a/bindings/zig/src/opendal.zig
+++ b/bindings/zig/test/bdd.zig
@@ -15,16 +15,16 @@
 // specific language governing permissions and limitations
 // under the License.
 
-pub const opendal = @cImport(@cInclude("opendal.h"));
-
+const opendal = @import("opendal");
 const std = @import("std");
 const testing = std.testing;
+const Code = opendal.Code;
 
 test "Opendal BDD test" {
     const c_str = [*:0]const u8; // define a type for 'const char*' in C
 
     const OpendalBDDTest = struct {
-        p: opendal.opendal_operator_ptr,
+        p: opendal.c.opendal_operator_ptr,
         scheme: c_str,
         path: c_str,
         content: c_str,
@@ -35,19 +35,19 @@ test "Opendal BDD test" {
             self.path = "test";
             self.content = "Hello, World!";
 
-            var options: opendal.opendal_operator_options = 
opendal.opendal_operator_options_new();
-            defer opendal.opendal_operator_options_free(&options);
-            opendal.opendal_operator_options_set(&options, "root", "/myroot");
+            var options: opendal.c.opendal_operator_options = 
opendal.c.opendal_operator_options_new();
+            defer opendal.c.opendal_operator_options_free(&options);
+            opendal.c.opendal_operator_options_set(&options, "root", 
"/myroot");
 
             // Given A new OpenDAL Blocking Operator
-            self.p = opendal.opendal_operator_new(self.scheme, &options);
+            self.p = opendal.c.opendal_operator_new(self.scheme, &options);
             std.debug.assert(self.p.ptr != null);
 
             return self;
         }
 
         pub fn deinit(self: *Self) void {
-            opendal.opendal_operator_free(&self.p);
+            opendal.c.opendal_operator_free(&self.p);
         }
 
         const Self = @This();
@@ -57,33 +57,33 @@ test "Opendal BDD test" {
     defer testkit.deinit();
 
     // When Blocking write path "test" with content "Hello, World!"
-    const data: opendal.opendal_bytes = .{
+    const data: opendal.c.opendal_bytes = .{
         .data = testkit.content,
         // c_str does not have len field (.* is ptr)
         .len = std.mem.len(testkit.content),
     };
-    const code = opendal.opendal_operator_blocking_write(testkit.p, 
testkit.path, data);
-    try testing.expectEqual(code, opendal.OPENDAL_OK);
+    const code = opendal.c.opendal_operator_blocking_write(testkit.p, 
testkit.path, data);
+    try testing.expectEqual(code, @enumToInt(Code.OK));
 
     // The blocking file "test" should exist
-    var e: opendal.opendal_result_is_exist = 
opendal.opendal_operator_is_exist(testkit.p, testkit.path);
-    try testing.expectEqual(e.code, opendal.OPENDAL_OK);
+    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.expect(e.is_exist);
 
     // The blocking file "test" entry mode must be file
-    var s: opendal.opendal_result_stat = 
opendal.opendal_operator_stat(testkit.p, testkit.path);
-    try testing.expectEqual(s.code, opendal.OPENDAL_OK);
-    var meta: opendal.opendal_metadata = s.meta;
-    try testing.expect(opendal.opendal_metadata_is_file(&meta));
+    var s: opendal.c.opendal_result_stat = 
opendal.c.opendal_operator_stat(testkit.p, testkit.path);
+    try testing.expectEqual(s.code, @enumToInt(Code.OK));
+    var meta: opendal.c.opendal_metadata = s.meta;
+    try testing.expect(opendal.c.opendal_metadata_is_file(&meta));
 
     // The blocking file "test" content length must be 13
-    try testing.expectEqual(opendal.opendal_metadata_content_length(&meta), 
13);
-    defer opendal.opendal_metadata_free(&meta);
+    try testing.expectEqual(opendal.c.opendal_metadata_content_length(&meta), 
13);
+    defer opendal.c.opendal_metadata_free(&meta);
 
     // The blocking file "test" must have content "Hello, World!"
-    var r: opendal.opendal_result_read = 
opendal.opendal_operator_blocking_read(testkit.p, testkit.path);
-    defer opendal.opendal_bytes_free(r.data);
-    try testing.expect(r.code == opendal.OPENDAL_OK);
+    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.expectEqual(std.mem.len(testkit.content), r.data.*.len);
 
     var count: usize = 0;
@@ -91,3 +91,7 @@ test "Opendal BDD test" {
         try testing.expectEqual(testkit.content[count], r.data.*.data[count]);
     }
 }
+
+test "Semantic Analyzer" {
+    testing.refAllDeclsRecursive(@This());
+}

Reply via email to