authorgravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-01-02 19:13:30 -08:00
committergravatar for hello@nektro.netMeghan Denny <hello@nektro.net> 2026-01-02 19:13:30 -08:00
logbe47f81f8219ed513b68acd398a3e24bb8276afc
tree9a1fb18bba74c5a7dee8c8d95c59511c41d302db
parent1167b69d98220fd017d1721a85a5cc6a0fca8774

vastly improve errno.fromInt()


1 files changed, 22 insertions(+), 24 deletions(-)

mod.zig+22-24
...@@ -894,34 +894,32 @@ pub const errno = struct {...@@ -894,34 +894,32 @@ pub const errno = struct {
894 return null;894 return null;
895 }895 }
896896
897 const map = blk: {897 comptime {
898 const KV = struct { []const u8, Error };898 // assert Enum is sequential
899 var kvs: []const KV = &.{};899 var value: c_ushort = 0; // SUCCESS
900 for (std.meta.fields(Enum)) |field| {900 for (std.enums.values(Enum)) |val| {
901 kvs = kvs ++ &[1]KV{.{ field.name, @field(Error, field.name) }};901 std.debug.assert(@intFromEnum(val) > value);
902 value = @intFromEnum(val);
902 }903 }
903 break :blk std.StaticStringMap(Error).initComptime(kvs);904 }
905 comptime {
906 // sanity test
907 std.debug.assert(@intFromEnum(Enum.EPERM) == 1);
908 }
909 const list = blk: {
910 const values = std.enums.values(Enum);
911 const len = @intFromEnum(values[values.len - 1]) + 1;
912 var errors: [len]Error = @splat(error.Unexpected);
913 for (values) |f| errors[@intFromEnum(f)] = @field(Error, @tagName(f));
914 const final = errors;
915 break :blk final;
904 };916 };
905917
906 pub fn fromInt(code: c_int) Error {918 pub fn fromInt(code: c_int) Error {
907 const errors_are_seqential = comptime blk: {919 @setRuntimeSafety(false);
908 if (@intFromEnum(Enum.EPERM) != 1) break :blk false;920 if (code >= list.len) return error.Unexpected;
909 var prev: u16 = @intFromError(Error.EPERM);921 if (code <= 0) return error.Unexpected;
910 for (std.meta.fields(Error)[1..]) |field| {922 return list[@intCast(code)];
911 const int = @intFromError(@field(anyerror, field.name));
912 if (int != prev + 1) break :blk false;
913 prev = int;
914 }
915 break :blk true;
916 };
917 if (errors_are_seqential) {
918 // avoid an inline for and N comparisons
919 if (code < 1) return error.Unexpected;
920 if (code > std.meta.fields(Enum).len) return error.Unexpected;
921 const ucode: c_ushort = @intCast(code);
922 return @errorCast(@errorFromInt(@intFromError(Error.EPERM) + ucode - @intFromEnum(Enum.EPERM)));
923 }
924 return map.get(std.enums.tagName(Enum, @enumFromInt(code)) orelse return error.Unexpected).?;
925 }923 }
926924
927 pub fn fromLibC() c_int {925 pub fn fromLibC() c_int {