miaan15/zig-exception
A small generic result/exception wrapper for Zig
A small generic result/exception wrapper for Zig.
It allows you to wrap a success-value type and an error tag + payload, similar to std::exception in C++.
Exception(T, ETag, EPayload):T = the success type ETag = an error tag type (e.g. an error{…} enum) EPayload = an arbitrary payload type carried along with errors.ok(value) → success .err(tag, payload) → error.get() → returns ETag!T (i.e. either success value or error tag) .get_ok() → returns !T (error if trying to get ok from an error) .get_err() → returns !E (where E contains tag + payload; error if trying on an ok)zig build run
zig build test
const std = @import("std");
const Exception = @import("exception").Exception;
const MyError = error{ Zero, Negetive };
// result might be i32 if success; return MyError and message if error:
const ResultI32 = Exception(i32, MyError, []const u8);
pub fn foo(x: i32) ResultI32 {
if (x < 0) {
return ResultI32.err(MyError.Negetive, "x was negative");
}
if (x == 0) {
return ResultI32.err(MyError.Zero, "x was zero");
}
return ResultI32.ok(x * 2);
}
pub fn main() !void {
// expect error
const r1 = foo(-5);
std.debug.print("Case: x = -5\n", .{});
if (r1.get()) |ok_val| {
std.debug.print("Success value (x * 2): {d}\n", .{ok_val});
} else |err_tag| {
std.debug.print("Error tag: {s}\n", .{@errorName(err_tag)});
const err_info = try r1.get_err();
std.debug.print(" payload: \"{s}\"\n", .{err_info.payload});
}
// expect success
const r2 = foo(10);
std.debug.print("\nCase: x = 10\n", .{});
const val = r2.get() catch |e| {
std.debug.print("Error tag: {s}\n", .{@errorName(e)});
return;
};
std.debug.print("Success value (x * 2): {d}\n", .{val});
}
Case: x = -5
Error tag: Negetive
payload: "x was negative"
Case: x = 10
Success value (x * 2): 20