Zig utility library
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

`result` is pretty much useless, functions can just return an union.

IamPyu 5ecc956b 1529d0b4

-122
-118
src/result.zig
··· 1 - const std = @import("std"); 2 - const Type = std.builtin.Type; 3 - 4 - pub const ResultTag = enum { Ok, Err }; 5 - 6 - /// Result 7 - /// 8 - /// The primary purpose of this as an alternative to Zig's error handling 9 - /// is to handle errors that may provide a payload instead of just the 10 - /// error type, otherwise Zig's error handling should be used. 11 - /// 12 - /// `E` must be a tagged union of possible error types with their payloads. 13 - pub fn Result(comptime T: type, comptime E: type) type { 14 - const error_info = @typeInfo(E); 15 - std.debug.assert(std.meta.activeTag(error_info) == .@"union"); 16 - 17 - const Error: type = blk: { 18 - comptime var errors: [error_info.@"union".fields.len]Type.Error = undefined; 19 - inline for (error_info.@"union".fields, 0..) |field, i| { 20 - errors[i] = Type.Error{ .name = field.name }; 21 - } 22 - 23 - break :blk @Type(Type{ .error_set = &errors }); 24 - }; 25 - const ErrorTag = std.meta.Tag(E); 26 - const N = error_info.@"union".fields.len; 27 - 28 - const lookup = comptime blk: { 29 - var lookup: struct { 30 - keys: [N]ErrorTag, 31 - values: [N]Error, 32 - } = .{ 33 - .keys = undefined, 34 - .values = undefined, 35 - }; 36 - 37 - for (std.meta.tags(ErrorTag), std.meta.tags(Error), 0..) |key, value, i| { 38 - lookup.keys[i] = key; 39 - lookup.values[i] = value; 40 - } 41 - 42 - break :blk lookup; 43 - }; 44 - 45 - return union(ResultTag) { 46 - Ok: T, 47 - Err: E, 48 - 49 - const Self = @This(); 50 - 51 - /// Generated error type 52 - pub const ErrorType = Error; 53 - 54 - /// Wrap `value` as an Ok result 55 - pub fn ok(value: T) Self { 56 - return .{ .Ok = value }; 57 - } 58 - 59 - /// Wrap `value` as an Err result 60 - pub fn err(value: E) Self { 61 - return .{ .Err = value }; 62 - } 63 - 64 - /// Returns true if `self` is Ok 65 - pub fn isOk(self: *const Self) bool { 66 - return std.meta.activeTag(self.*) == .Ok; 67 - } 68 - 69 - /// Returns true if `self` is Err 70 - pub fn isErr(self: *const Self) bool { 71 - return std.meta.activeTag(self.*) == .Err; 72 - } 73 - 74 - fn getError(self: *const Self) Error { 75 - const tag: ErrorTag = std.meta.activeTag(self.Err); 76 - const idx = std.mem.indexOfScalar(ErrorTag, &lookup.keys, tag) orelse unreachable; 77 - return lookup.values[idx]; 78 - } 79 - 80 - /// Unwrap the Ok value in `self` 81 - pub fn unwrap(self: Self) Error!T { 82 - if (self.isErr()) { 83 - return self.getError(); 84 - } else { 85 - return self.Ok; 86 - } 87 - } 88 - 89 - /// Unwrap the Ok value in `self` or return null 90 - pub fn unwrapOrNull(self: Self) ?T { 91 - return self.unwrap() catch null; 92 - } 93 - }; 94 - } 95 - 96 - const ExampleError = union(enum) { 97 - False: []const u8, 98 - }; 99 - 100 - fn example(b: bool) Result(u32, ExampleError) { 101 - if (b) { 102 - return .ok(43); 103 - } else { 104 - return .err(.{ .False = "error message" }); 105 - } 106 - } 107 - 108 - test "result" { 109 - try std.testing.expectEqual(43, try example(true).unwrap()); 110 - 111 - const result = example(false); 112 - if (result.unwrap()) |n| { 113 - _ = n; 114 - // do stuff 115 - } else |_| switch (result.Err) { 116 - .False => |s| std.debug.print("error: {s}\n", .{s}), 117 - } 118 - }
-4
src/root.zig
··· 13 13 pub const data = @import("./data/root.zig"); 14 14 pub const gamedev = @import("./gamedev/root.zig"); 15 15 16 - const result = @import("./result.zig"); 17 - pub const Result = result.Result; 18 - 19 16 pub const flag = @import("./flag.zig"); 20 17 21 18 test { ··· 28 25 _ = data; 29 26 _ = gamedev; 30 27 31 - _ = result; 32 28 _ = flag; 33 29 }