From 535fef7c2fc76772ca5c5ecd1fff1a26e19c1844 Mon Sep 17 00:00:00 2001 From: treeform Date: Mon, 25 May 2026 11:13:48 -0700 Subject: [PATCH] Improve Zig ergonomics --- src/genny/languages/zig.nim | 62 ++++++++-------- tests/generated/test.zig | 76 ++++++++++---------- tests/test_pixie_zig.zig | 136 +++++++++++++++++++----------------- tests/test_zig.zig | 13 ++-- 4 files changed, 150 insertions(+), 137 deletions(-) diff --git a/src/genny/languages/zig.nim b/src/genny/languages/zig.nim index 62f07f8..63ce90f 100644 --- a/src/genny/languages/zig.nim +++ b/src/genny/languages/zig.nim @@ -106,17 +106,15 @@ proc exportProc( indent = false, comments = "" ) = - let onClass = owner notin ["void", ""] - let indent = - if onClass: - true - else: - indent - - if indent: - code.add " " + let + onClass = owner notin ["void", ""] + baseIndent = + if onClass or indent: + " " + else: + "" - code.add &"extern fn {apiProcName}(" + code.add &"{baseIndent}extern fn {apiProcName}(" for i, param in procParams: if onClass and i == 0: code.add "self" @@ -126,7 +124,7 @@ proc exportProc( code.add exportTypeZigAbi(param[1]) code.add &", " code.removeSuffix ", " - code.add ") callconv(.C) " + code.add ") " if procReturn != "": code.add exportTypeZigAbi(procReturn); else: @@ -137,14 +135,9 @@ proc exportProc( for line in comments.split("\n"): var line = line line.removePrefix("##") - if indent: - code.add " " - code.add "/// " & line.strip() & "\n" - - if indent: - code.add " " + code.add &"{baseIndent}/// " & line.strip() & "\n" - code.add &"pub inline fn {procName}(" + code.add &"{baseIndent}pub inline fn {procName}(" for i, param in procParams[0 .. ^1]: if onClass and i == 0: code.add "self" @@ -155,6 +148,8 @@ proc exportProc( code.add &", " code.removeSuffix ", " code.add ") " + if procRaises: + code.add "Error!" if procReturn != "": code.add procReturn; else: @@ -162,10 +157,6 @@ proc exportProc( code.add " " code.add "{\n" - if indent: - code.add " " - code.add " return " - var call = "" call.add apiProcName call.add "(" @@ -180,11 +171,22 @@ proc exportProc( call.add ", " call.removeSuffix ", " call.add &")" - code.add convertImportToZig(call, procReturn) - code.add ";\n" - if indent: - code.add " " - code.add "}\n\n" + + if procRaises: + let hasReturn = procReturn notin ["", "void"] + if hasReturn: + code.add &"{baseIndent} const result = {call};\n" + else: + code.add &"{baseIndent} {call};\n" + code.add &"{baseIndent} if (checkError()) return error.$LibError;\n" + if hasReturn: + let resultValue = convertImportToZig("result", procReturn) + code.add &"{baseIndent} return {resultValue};\n" + else: + code.add &"{baseIndent} return;\n" + else: + code.add &"{baseIndent} return {convertImportToZig(call, procReturn)};\n" + code.add baseIndent & "}\n\n" proc exportProcZig*( sym: NimNode, @@ -287,7 +289,7 @@ proc genRefObject(objName: string) = code.add &"pub const {objName} = opaque " & "{\n" let unrefLibProc = &"$lib_{toSnakeCase(objName)}_unref" - code.add &" extern fn {unrefLibProc}(self: *{objName}) callconv(.C) void;\n" + code.add &" extern fn {unrefLibProc}(self: *{objName}) void;\n" code.add &" pub inline fn deinit(self: *{objName}) void " & "{\n" code.add &" return {unrefLibProc}(self);\n" code.add " }\n\n" @@ -400,6 +402,10 @@ proc exportSeqZig*(sym: NimNode) = const header = """ const std = @import("std"); +pub const Error = error{ + $LibError, +}; + """ proc writeZig*(dir, lib: string) = diff --git a/tests/generated/test.zig b/tests/generated/test.zig index 4698a99..8a90dd6 100644 --- a/tests/generated/test.zig +++ b/tests/generated/test.zig @@ -1,5 +1,9 @@ const std = @import("std"); +pub const Error = error{ + testError, +}; + pub const simple_const = 123; pub const SimpleEnum = enum(u8) { @@ -8,7 +12,7 @@ pub const SimpleEnum = enum(u8) { third = 2, }; -extern fn test_simple_call(a: isize) callconv(.C) isize; +extern fn test_simple_call(a: isize) isize; /// Returns the integer passed in. pub inline fn simpleCall(a: isize) isize { return test_simple_call(a); @@ -27,45 +31,45 @@ pub const SimpleObj = extern struct { }; } - extern fn test_simple_obj_eq(self: SimpleObj, other: SimpleObj) callconv(.C) bool; + extern fn test_simple_obj_eq(self: SimpleObj, other: SimpleObj) bool; pub inline fn eql(self: SimpleObj, other: SimpleObj) bool { return test_simple_obj_eq(self, other); } }; pub const SimpleRefObj = opaque { - extern fn test_simple_ref_obj_unref(self: *SimpleRefObj) callconv(.C) void; + extern fn test_simple_ref_obj_unref(self: *SimpleRefObj) void; pub inline fn deinit(self: *SimpleRefObj) void { return test_simple_ref_obj_unref(self); } - extern fn test_new_simple_ref_obj() callconv(.C) *SimpleRefObj; + extern fn test_new_simple_ref_obj() *SimpleRefObj; /// Creates new SimpleRefObj. pub inline fn init() *SimpleRefObj { return test_new_simple_ref_obj(); } - extern fn test_simple_ref_obj_get_simple_ref_a(self: *SimpleRefObj) callconv(.C) isize; + extern fn test_simple_ref_obj_get_simple_ref_a(self: *SimpleRefObj) isize; pub inline fn getSimpleRefA(self: *SimpleRefObj) isize { return test_simple_ref_obj_get_simple_ref_a(self); } - extern fn test_simple_ref_obj_set_simple_ref_a(self: *SimpleRefObj, value: isize) callconv(.C) void; + extern fn test_simple_ref_obj_set_simple_ref_a(self: *SimpleRefObj, value: isize) void; pub inline fn setSimpleRefA(self: *SimpleRefObj, value: isize) void { return test_simple_ref_obj_set_simple_ref_a(self, value); } - extern fn test_simple_ref_obj_get_simple_ref_b(self: *SimpleRefObj) callconv(.C) u8; + extern fn test_simple_ref_obj_get_simple_ref_b(self: *SimpleRefObj) u8; pub inline fn getSimpleRefB(self: *SimpleRefObj) u8 { return test_simple_ref_obj_get_simple_ref_b(self); } - extern fn test_simple_ref_obj_set_simple_ref_b(self: *SimpleRefObj, value: u8) callconv(.C) void; + extern fn test_simple_ref_obj_set_simple_ref_b(self: *SimpleRefObj, value: u8) void; pub inline fn setSimpleRefB(self: *SimpleRefObj, value: u8) void { return test_simple_ref_obj_set_simple_ref_b(self, value); } - extern fn test_simple_ref_obj_doit(self: *SimpleRefObj) callconv(.C) void; + extern fn test_simple_ref_obj_doit(self: *SimpleRefObj) void; /// Does some thing with SimpleRefObj. pub inline fn doit(self: *SimpleRefObj) void { return test_simple_ref_obj_doit(self); @@ -73,85 +77,85 @@ pub const SimpleRefObj = opaque { }; pub const SeqInt = opaque { - extern fn test_seq_int_unref(self: *SeqInt) callconv(.C) void; + extern fn test_seq_int_unref(self: *SeqInt) void; pub inline fn deinit(self: *SeqInt) void { return test_seq_int_unref(self); } - extern fn test_new_seq_int() callconv(.C) *SeqInt; + extern fn test_new_seq_int() *SeqInt; pub inline fn init() *SeqInt { return test_new_seq_int(); } - extern fn test_seq_int_len(self: *SeqInt) callconv(.C) isize; + extern fn test_seq_int_len(self: *SeqInt) isize; pub inline fn len(self: *SeqInt) isize { return test_seq_int_len(self); } - extern fn test_seq_int_get(self: *SeqInt, index: isize) callconv(.C) isize; + extern fn test_seq_int_get(self: *SeqInt, index: isize) isize; pub inline fn get(self: *SeqInt, index: isize) isize { return test_seq_int_get(self, index); } - extern fn test_seq_int_set(self: *SeqInt, index: isize, value: isize) callconv(.C) void; + extern fn test_seq_int_set(self: *SeqInt, index: isize, value: isize) void; pub inline fn set(self: *SeqInt, index: isize, value: isize) void { return test_seq_int_set(self, index, value); } - extern fn test_seq_int_add(self: *SeqInt, value: isize) callconv(.C) void; + extern fn test_seq_int_add(self: *SeqInt, value: isize) void; pub inline fn append(self: *SeqInt, value: isize) void { return test_seq_int_add(self, value); } - extern fn test_seq_int_delete(self: *SeqInt, index: isize) callconv(.C) void; + extern fn test_seq_int_delete(self: *SeqInt, index: isize) void; pub inline fn remove(self: *SeqInt, index: isize) void { return test_seq_int_delete(self, index); } - extern fn test_seq_int_clear(self: *SeqInt) callconv(.C) void; + extern fn test_seq_int_clear(self: *SeqInt) void; pub inline fn clear(self: *SeqInt) void { return test_seq_int_clear(self); } }; pub const RefObjWithSeq = opaque { - extern fn test_ref_obj_with_seq_unref(self: *RefObjWithSeq) callconv(.C) void; + extern fn test_ref_obj_with_seq_unref(self: *RefObjWithSeq) void; pub inline fn deinit(self: *RefObjWithSeq) void { return test_ref_obj_with_seq_unref(self); } - extern fn test_new_ref_obj_with_seq() callconv(.C) *RefObjWithSeq; + extern fn test_new_ref_obj_with_seq() *RefObjWithSeq; /// Creates new SimpleRefObj. pub inline fn init() *RefObjWithSeq { return test_new_ref_obj_with_seq(); } - extern fn test_ref_obj_with_seq_data_len(self: *RefObjWithSeq) callconv(.C) isize; + extern fn test_ref_obj_with_seq_data_len(self: *RefObjWithSeq) isize; pub inline fn lenData(self: *RefObjWithSeq) isize { return test_ref_obj_with_seq_data_len(self); } - extern fn test_ref_obj_with_seq_data_get(self: *RefObjWithSeq, index: isize) callconv(.C) u8; + extern fn test_ref_obj_with_seq_data_get(self: *RefObjWithSeq, index: isize) u8; pub inline fn getData(self: *RefObjWithSeq, index: isize) u8 { return test_ref_obj_with_seq_data_get(self, index); } - extern fn test_ref_obj_with_seq_data_set(self: *RefObjWithSeq, index: isize, value: u8) callconv(.C) void; + extern fn test_ref_obj_with_seq_data_set(self: *RefObjWithSeq, index: isize, value: u8) void; pub inline fn setData(self: *RefObjWithSeq, index: isize, value: u8) void { return test_ref_obj_with_seq_data_set(self, index, value); } - extern fn test_ref_obj_with_seq_data_add(self: *RefObjWithSeq, value: u8) callconv(.C) void; + extern fn test_ref_obj_with_seq_data_add(self: *RefObjWithSeq, value: u8) void; pub inline fn appendData(self: *RefObjWithSeq, value: u8) void { return test_ref_obj_with_seq_data_add(self, value); } - extern fn test_ref_obj_with_seq_data_delete(self: *RefObjWithSeq, index: isize) callconv(.C) void; + extern fn test_ref_obj_with_seq_data_delete(self: *RefObjWithSeq, index: isize) void; pub inline fn removeData(self: *RefObjWithSeq, index: isize) void { return test_ref_obj_with_seq_data_delete(self, index); } - extern fn test_ref_obj_with_seq_data_clear(self: *RefObjWithSeq) callconv(.C) void; + extern fn test_ref_obj_with_seq_data_clear(self: *RefObjWithSeq) void; pub inline fn clearData(self: *RefObjWithSeq) void { return test_ref_obj_with_seq_data_clear(self); } @@ -170,60 +174,60 @@ pub const SimpleObjWithProc = extern struct { }; } - extern fn test_simple_obj_with_proc_eq(self: SimpleObjWithProc, other: SimpleObjWithProc) callconv(.C) bool; + extern fn test_simple_obj_with_proc_eq(self: SimpleObjWithProc, other: SimpleObjWithProc) bool; pub inline fn eql(self: SimpleObjWithProc, other: SimpleObjWithProc) bool { return test_simple_obj_with_proc_eq(self, other); } - extern fn test_simple_obj_with_proc_extra_proc(self: SimpleObjWithProc) callconv(.C) void; + extern fn test_simple_obj_with_proc_extra_proc(self: SimpleObjWithProc) void; pub inline fn extraProc(self: SimpleObjWithProc) void { return test_simple_obj_with_proc_extra_proc(self); } }; pub const SeqString = opaque { - extern fn test_seq_string_unref(self: *SeqString) callconv(.C) void; + extern fn test_seq_string_unref(self: *SeqString) void; pub inline fn deinit(self: *SeqString) void { return test_seq_string_unref(self); } - extern fn test_new_seq_string() callconv(.C) *SeqString; + extern fn test_new_seq_string() *SeqString; pub inline fn init() *SeqString { return test_new_seq_string(); } - extern fn test_seq_string_len(self: *SeqString) callconv(.C) isize; + extern fn test_seq_string_len(self: *SeqString) isize; pub inline fn len(self: *SeqString) isize { return test_seq_string_len(self); } - extern fn test_seq_string_get(self: *SeqString, index: isize) callconv(.C) [*:0]const u8; + extern fn test_seq_string_get(self: *SeqString, index: isize) [*:0]const u8; pub inline fn get(self: *SeqString, index: isize) [:0]const u8 { return std.mem.span(test_seq_string_get(self, index)); } - extern fn test_seq_string_set(self: *SeqString, index: isize, value: [*:0]const u8) callconv(.C) void; + extern fn test_seq_string_set(self: *SeqString, index: isize, value: [*:0]const u8) void; pub inline fn set(self: *SeqString, index: isize, value: [:0]const u8) void { return test_seq_string_set(self, index, value.ptr); } - extern fn test_seq_string_add(self: *SeqString, value: [*:0]const u8) callconv(.C) void; + extern fn test_seq_string_add(self: *SeqString, value: [*:0]const u8) void; pub inline fn append(self: *SeqString, value: [:0]const u8) void { return test_seq_string_add(self, value.ptr); } - extern fn test_seq_string_delete(self: *SeqString, index: isize) callconv(.C) void; + extern fn test_seq_string_delete(self: *SeqString, index: isize) void; pub inline fn remove(self: *SeqString, index: isize) void { return test_seq_string_delete(self, index); } - extern fn test_seq_string_clear(self: *SeqString) callconv(.C) void; + extern fn test_seq_string_clear(self: *SeqString) void; pub inline fn clear(self: *SeqString) void { return test_seq_string_clear(self); } }; -extern fn test_get_datas() callconv(.C) *SeqString; +extern fn test_get_datas() *SeqString; pub inline fn getDatas() *SeqString { return test_get_datas(); } diff --git a/tests/test_pixie_zig.zig b/tests/test_pixie_zig.zig index ff73949..1406f2b 100644 --- a/tests/test_pixie_zig.zig +++ b/tests/test_pixie_zig.zig @@ -25,8 +25,8 @@ pub fn main() !void { try expect(@intFromEnum(pixie.FileFormat.png_format) == 0); try expect(@intFromEnum(pixie.PaintKind.linear_gradient_paint) == 3); - const red = pixie.parseColor("#ff0000"); - const green = pixie.parseColor("#00ff00"); + const red = try pixie.parseColor("#ff0000"); + const green = try pixie.parseColor("#00ff00"); const mixed = pixie.mix(red, green, 0.25); try approx(mixed.r, 0.75); try approx(mixed.g, 0.25); @@ -47,11 +47,11 @@ pub fn main() !void { try expect(dashes.len() == 2); try approx(dashes.get(1), 3.5); - const image = pixie.Image.init(4, 3); + const image = try pixie.Image.init(4, 3); defer image.deinit(); try expect(image.getWidth() == 4); try expect(image.getHeight() == 3); - try expect(image.encodeBase64().len > 20); + try expect((try image.encodeBase64()).len > 20); image.fill(red); try expect(image.isOneColor()); try expect(image.isOpaque()); @@ -65,29 +65,29 @@ pub fn main() !void { const solid = pixie.Paint.init(.solid_paint); defer solid.deinit(); solid.setColor(red); - image.fillPaint(solid); + try image.fillPaint(solid); image.applyOpacity(0.5); try approxEps(image.getColor(0, 0).a, 0.5, 0.01); image.invert(); - image.blur(1, red); + try image.blur(1, red); - const resized = image.resize(6, 5); + const resized = try image.resize(6, 5); defer resized.deinit(); try expect(resized.getWidth() == 6); try expect(resized.getHeight() == 5); - resized.rotate90(); + try resized.rotate90(); try expect(resized.getWidth() == 5); try expect(resized.getHeight() == 6); - const sub = resized.subImage(0, 0, 2, 2); + const sub = try resized.subImage(0, 0, 2, 2); defer sub.deinit(); try expect(sub.getWidth() == 2); - const rect_sub = resized.subImageRect(pixie.Rect.init(0, 0, 1, 1)); + const rect_sub = try resized.subImageRect(pixie.Rect.init(0, 0, 1, 1)); defer rect_sub.deinit(); try expect(rect_sub.getHeight() == 1); - const shadow = resized.shadow(pixie.Vector2.init(1, 2), 3, 4, red); + const shadow = try resized.shadow(pixie.Vector2.init(1, 2), 3, 4, red); defer shadow.deinit(); try expect(shadow.getWidth() == resized.getWidth()); - const super_image = resized.superImage(-1, -1, resized.getWidth() + 2, resized.getHeight() + 2); + const super_image = try resized.superImage(-1, -1, resized.getWidth() + 2, resized.getHeight() + 2); defer super_image.deinit(); try expect(super_image.getWidth() == resized.getWidth() + 2); try expect(resized.opaqueBounds().w > 0); @@ -118,33 +118,33 @@ pub fn main() !void { path.bezierCurveTo(1, 2, 3, 4, 5, 6); path.quadraticCurveTo(1, 2, 3, 4); path.ellipticalArcTo(1, 2, 3, false, true, 4, 5); - path.arc(1, 2, 3, 0, 1, false); - path.arcTo(1, 2, 3, 4, 5); + try path.arc(1, 2, 3, 0, 1, false); + try path.arcTo(1, 2, 3, 4, 5); path.rect(0, 0, 3, 4, true); path.roundedRect(0, 0, 3, 4, 1, 1, 1, 1, true); path.ellipse(1, 2, 3, 4); path.circle(1, 2, 3); - path.polygon(1, 2, 3, 5); + try path.polygon(1, 2, 3, 5); path.closePath(); - try expect(path.computeBounds(identity).w > 0); + try expect((try path.computeBounds(identity)).w > 0); const rect_path = pixie.Path.init(); defer rect_path.deinit(); rect_path.rect(0, 0, 10, 10, true); const solid_dashes = pixie.SeqFloat32.init(); defer solid_dashes.deinit(); - try expect(rect_path.fillOverlaps(pixie.Vector2.init(5, 5), identity, .non_zero)); - try expect(rect_path.strokeOverlaps(pixie.Vector2.init(0, 5), identity, 2, .butt_cap, .miter_join, pixie.default_miter_limit, solid_dashes)); + try expect(try rect_path.fillOverlaps(pixie.Vector2.init(5, 5), identity, .non_zero)); + try expect(try rect_path.strokeOverlaps(pixie.Vector2.init(0, 5), identity, 2, .butt_cap, .miter_join, pixie.default_miter_limit, solid_dashes)); - const typeface = pixie.readTypeface(font_path); + const typeface = try pixie.readTypeface(font_path); defer typeface.deinit(); try expect(std.mem.endsWith(u8, typeface.getFilePath(), "Inter-Regular.ttf")); typeface.setFilePath(font_path); try expect(typeface.hasGlyph('A')); try expect(typeface.getAdvance('A') > 0); - const glyph = typeface.getGlyphPath('A'); + const glyph = try typeface.getGlyphPath('A'); defer glyph.deinit(); - try expect(glyph.computeBounds(identity).w > 0); + try expect((try glyph.computeBounds(identity)).w > 0); const font = typeface.newFont(); defer font.deinit(); @@ -175,19 +175,19 @@ pub fn main() !void { try expect(std.mem.eql(u8, spans.get(0).getText(), "hello")); try expect(arrangement.layoutBounds().x > 0); try expect(spans.layoutBounds().y > 0); - try expect(arrangement.computeBounds(mat).x > 0); + try expect((try arrangement.computeBounds(mat)).x > 0); - const canvas = pixie.Image.init(64, 64); + const canvas = try pixie.Image.init(64, 64); defer canvas.deinit(); - canvas.fill(pixie.parseColor("#ffffff")); - canvas.fillText(font, "abc", mat, pixie.Vector2.init(60, 60), .left_align, .top_align); - canvas.fillTextArrangement(arrangement, mat); - canvas.strokeText(font, "abc", mat, 2, pixie.Vector2.init(60, 60), .left_align, .top_align, .butt_cap, .miter_join, pixie.default_miter_limit, dashes); - canvas.strokeTextArrangement(arrangement, mat, 2, .butt_cap, .miter_join, pixie.default_miter_limit, dashes); - canvas.fillPath(rect_path, solid, mat, .non_zero); - canvas.strokePath(rect_path, solid, mat, 2, .butt_cap, .miter_join, pixie.default_miter_limit, dashes); + canvas.fill(try pixie.parseColor("#ffffff")); + try canvas.fillText(font, "abc", mat, pixie.Vector2.init(60, 60), .left_align, .top_align); + try canvas.fillTextArrangement(arrangement, mat); + try canvas.strokeText(font, "abc", mat, 2, pixie.Vector2.init(60, 60), .left_align, .top_align, .butt_cap, .miter_join, pixie.default_miter_limit, dashes); + try canvas.strokeTextArrangement(arrangement, mat, 2, .butt_cap, .miter_join, pixie.default_miter_limit, dashes); + try canvas.fillPath(rect_path, solid, mat, .non_zero); + try canvas.strokePath(rect_path, solid, mat, 2, .butt_cap, .miter_join, pixie.default_miter_limit, dashes); - const ctx = pixie.Context.init(80, 80); + const ctx = try pixie.Context.init(80, 80); defer ctx.deinit(); ctx.setGlobalAlpha(0.75); ctx.setLineWidth(2); @@ -198,7 +198,7 @@ pub fn main() !void { ctx.setFontSize(24); ctx.setTextAlign(.right_align); try expect(ctx.getTextAlign() == .right_align); - try expect(ctx.measureText("abcd").width > 0); + try expect((try ctx.measureText("abcd")).width > 0); ctx.setTransform(mat); try expect(ctx.getTransform().values[6] == 3); ctx.transform(pixie.scale(2, 2)); @@ -206,10 +206,10 @@ pub fn main() !void { ctx.setLineDash(solid_dashes); ctx.beginPath(); ctx.rect(0, 0, 10, 10); - try expect(ctx.isPointInPath(5, 5, .non_zero)); - try expect(ctx.isPointInPathPath(rect_path, 5, 5, .non_zero)); - try expect(ctx.isPointInStroke(0, 5)); - try expect(ctx.isPointInStrokePath(rect_path, 0, 5)); + try expect(try ctx.isPointInPath(5, 5, .non_zero)); + try expect(try ctx.isPointInPathPath(rect_path, 5, 5, .non_zero)); + try expect(try ctx.isPointInStroke(0, 5)); + try expect(try ctx.isPointInStrokePath(rect_path, 0, 5)); ctx.setLineDash(dashes); const ctx_dashes = ctx.getLineDash(); defer ctx_dashes.deinit(); @@ -218,56 +218,60 @@ pub fn main() !void { ctx.lineTo(2, 2); ctx.bezierCurveTo(1, 2, 3, 4, 5, 6); ctx.quadraticCurveTo(1, 2, 3, 4); - ctx.arc(1, 2, 3, 0, 1, false); - ctx.arcTo(1, 2, 3, 4, 5); + try ctx.arc(1, 2, 3, 0, 1, false); + try ctx.arcTo(1, 2, 3, 4, 5); ctx.roundedRect(0, 0, 3, 4, 1, 1, 1, 1); ctx.ellipse(1, 2, 3, 4); ctx.circle(1, 2, 3); - ctx.polygon(1, 2, 3, 5); + try ctx.polygon(1, 2, 3, 5); ctx.closePath(); - ctx.fill(.non_zero); - ctx.fillPath(rect_path, .even_odd); - ctx.clip(.non_zero); - ctx.clipPath(rect_path, .even_odd); - ctx.stroke(); - ctx.strokePath(rect_path); - ctx.drawImage(canvas, 1, 2); - ctx.drawImage2(canvas, 1, 2, 3, 4); - ctx.drawImage3(canvas, 1, 2, 3, 4, 5, 6, 7, 8); - ctx.clearRect(1, 2, 3, 4); - ctx.fillRect(1, 2, 3, 4); - ctx.strokeRect(1, 2, 3, 4); - ctx.strokeSegment(1, 2, 3, 4); - ctx.fillText("abc", 1, 2); - ctx.strokeText("abc", 1, 2); + try ctx.fill(.non_zero); + try ctx.fillPath(rect_path, .even_odd); + try ctx.clip(.non_zero); + try ctx.clipPath(rect_path, .even_odd); + try ctx.stroke(); + try ctx.strokePath(rect_path); + try ctx.drawImage(canvas, 1, 2); + try ctx.drawImage2(canvas, 1, 2, 3, 4); + try ctx.drawImage3(canvas, 1, 2, 3, 4, 5, 6, 7, 8); + try ctx.clearRect(1, 2, 3, 4); + try ctx.fillRect(1, 2, 3, 4); + try ctx.strokeRect(1, 2, 3, 4); + try ctx.strokeSegment(1, 2, 3, 4); + try ctx.fillText("abc", 1, 2); + try ctx.strokeText("abc", 1, 2); ctx.translate(3, 4); ctx.scale(2, 3); ctx.rotate(0.5); ctx.save(); - ctx.saveLayer(); - ctx.restore(); + try ctx.saveLayer(); + try ctx.restore(); - const decoded = pixie.decodeBase64(canvas.encodeBase64()); + const decoded = try pixie.decodeBase64(try canvas.encodeBase64()); defer decoded.deinit(); try expect(decoded.getWidth() == canvas.getWidth()); try expect(decoded.getHeight() == canvas.getHeight()); - const decoded_image = pixie.decodeImage(ppm); + const decoded_image = try pixie.decodeImage(ppm); defer decoded_image.deinit(); try expect(decoded_image.getWidth() == 2); - try expect(pixie.decodeImageDimensions(ppm).height == 1); - const read_image = pixie.readImage(image_path); + try expect((try pixie.decodeImageDimensions(ppm)).height == 1); + const read_image = try pixie.readImage(image_path); defer read_image.deinit(); try expect(read_image.getWidth() == 40); - try expect(pixie.readImageDimensions(image_path).height == 40); - const read_font = pixie.readFont(font_path); + try expect((try pixie.readImageDimensions(image_path)).height == 40); + const read_font = try pixie.readFont(font_path); defer read_font.deinit(); try approx(read_font.getSize(), 12); - const parsed_path = pixie.parsePath("M0 0 L10 0 L10 10 Z"); + const parsed_path = try pixie.parsePath("M0 0 L10 0 L10 10 Z"); defer parsed_path.deinit(); - try expect(parsed_path.computeBounds(identity).w == 10); - _ = pixie.parseColor("bad"); + try expect((try parsed_path.computeBounds(identity)).w == 10); + if (pixie.parseColor("bad")) |_| { + return error.TestFailed; + } else |err| { + try expect(err == error.PixieError); + } try expect(pixie.checkError()); try expect(std.mem.indexOf(u8, pixie.takeError(), "bad") != null); - try std.io.getStdOut().writer().print("All Pixie Zig tests passed!\n", .{}); + std.debug.print("All Pixie Zig tests passed!\n", .{}); } diff --git a/tests/test_zig.zig b/tests/test_zig.zig index 26f6f93..73e64dd 100644 --- a/tests/test_zig.zig +++ b/tests/test_zig.zig @@ -2,23 +2,22 @@ const std = @import("std"); const test_lib = @import("generated/test.zig"); pub fn main() !void { - const stdout = std.io.getStdOut().writer(); - try stdout.print("Testing Zig bindings\n", .{}); + std.debug.print("Testing Zig bindings\n", .{}); - try stdout.print("Testing simpleCall\n", .{}); + std.debug.print("Testing simpleCall\n", .{}); const result = test_lib.simpleCall(42); - try stdout.print("Result: {d}\n", .{result}); + std.debug.print("Result: {d}\n", .{result}); if (result != 42) { - try stdout.print("FAIL: expected 42, got {d}\n", .{result}); + std.debug.print("FAIL: expected 42, got {d}\n", .{result}); return error.TestFailed; } - try stdout.print("Testing SimpleObj\n", .{}); + std.debug.print("Testing SimpleObj\n", .{}); const obj = test_lib.SimpleObj.init(10, 20, true); if (obj.simple_a != 10) return error.TestFailed; if (obj.simple_b != 20) return error.TestFailed; if (obj.simple_c != true) return error.TestFailed; - try stdout.print("All Zig tests passed!\n", .{}); + std.debug.print("All Zig tests passed!\n", .{}); }