Skip to content

Commit 331dac8

Browse files
claude[bot]lalinsky
andcommitted
Refactor enum optional handling to use existing framework
- Remove custom backup reader mechanism (44 lines removed) - Use maybeUnpackNull(header, T) pattern like int.zig - Simplify getEnumSize to handle optionals recursively - Follow established unpackInt dispatch pattern for header handling - Maintains full compatibility with existing tests Co-authored-by: Lukáš Lalinský <lalinsky@users.noreply.github.com>
1 parent 32477dc commit 331dac8

File tree

1 file changed

+40
-60
lines changed

1 file changed

+40
-60
lines changed

src/enum.zig

Lines changed: 40 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,17 @@ pub fn getMaxEnumSize(comptime T: type) usize {
2626
}
2727

2828
pub fn getEnumSize(comptime T: type, value: T) usize {
29-
switch (@typeInfo(T)) {
30-
.@"enum" => {
31-
const tag_type = @typeInfo(T).@"enum".tag_type;
32-
const int_value = @intFromEnum(value);
33-
return getIntSize(tag_type, int_value);
34-
},
35-
.optional => |opt_info| {
36-
if (value) |v| {
37-
return getEnumSize(opt_info.child, v);
38-
} else {
39-
return 1; // size of null
40-
}
41-
},
42-
else => @compileError("Expected enum or optional enum, got " ++ @typeName(T)),
29+
if (@typeInfo(T) == .optional) {
30+
if (value) |v| {
31+
return getEnumSize(@typeInfo(T).optional.child, v);
32+
} else {
33+
return 1; // size of null
34+
}
4335
}
36+
37+
const tag_type = @typeInfo(T).@"enum".tag_type;
38+
const int_value = @intFromEnum(value);
39+
return getIntSize(tag_type, int_value);
4440
}
4541

4642
pub fn packEnum(writer: anytype, comptime T: type, value_or_maybe_null: T) !void {
@@ -54,52 +50,36 @@ pub fn packEnum(writer: anytype, comptime T: type, value_or_maybe_null: T) !void
5450
}
5551

5652
pub fn unpackEnum(reader: anytype, comptime T: type) !T {
57-
switch (@typeInfo(T)) {
58-
.@"enum" => {
59-
const tag_type = @typeInfo(T).@"enum".tag_type;
60-
const int_value = try unpackInt(reader, tag_type);
61-
return @enumFromInt(int_value);
62-
},
63-
.optional => |opt_info| {
64-
const header = try reader.readByte();
65-
if (header == hdrs.NIL) {
66-
return null;
67-
}
68-
69-
// Put the header back and unpack as non-optional enum
70-
// We need to create a buffered reader that includes the header
71-
const backup_reader = struct {
72-
header: u8,
73-
reader: @TypeOf(reader),
74-
header_consumed: bool = false,
75-
76-
const Self = @This();
77-
78-
pub fn readByte(self: *Self) !u8 {
79-
if (!self.header_consumed) {
80-
self.header_consumed = true;
81-
return self.header;
82-
}
83-
return try self.reader.readByte();
84-
}
85-
86-
pub fn readBytesNoEof(self: *Self, buf: []u8) !void {
87-
if (!self.header_consumed and buf.len > 0) {
88-
buf[0] = self.header;
89-
self.header_consumed = true;
90-
if (buf.len > 1) {
91-
try self.reader.readBytesNoEof(buf[1..]);
92-
}
93-
} else {
94-
try self.reader.readBytesNoEof(buf);
95-
}
96-
}
97-
};
98-
99-
var backup = backup_reader{ .header = header, .reader = reader };
100-
return try unpackEnum(backup.reader(), opt_info.child);
101-
},
102-
else => @compileError("Expected enum or optional enum, got " ++ @typeName(T)),
53+
const Type = assertEnumType(T);
54+
const tag_type = @typeInfo(Type).@"enum".tag_type;
55+
56+
const header = try reader.readByte();
57+
58+
if (header <= hdrs.POSITIVE_FIXINT_MAX) {
59+
return @enumFromInt(@as(tag_type, @intCast(header)));
60+
}
61+
62+
if (header >= hdrs.NEGATIVE_FIXINT_MIN) {
63+
const value: i8 = @bitCast(header);
64+
const tag_type_info = @typeInfo(tag_type);
65+
if (tag_type_info.int.signedness == .signed) {
66+
return @enumFromInt(@as(tag_type, value));
67+
} else if (value >= 0) {
68+
return @enumFromInt(@as(tag_type, @intCast(value)));
69+
}
70+
return error.IntegerOverflow;
71+
}
72+
73+
switch (header) {
74+
hdrs.INT8 => return @enumFromInt(try unpackIntValue(reader, i8, tag_type)),
75+
hdrs.INT16 => return @enumFromInt(try unpackIntValue(reader, i16, tag_type)),
76+
hdrs.INT32 => return @enumFromInt(try unpackIntValue(reader, i32, tag_type)),
77+
hdrs.INT64 => return @enumFromInt(try unpackIntValue(reader, i64, tag_type)),
78+
hdrs.UINT8 => return @enumFromInt(try unpackIntValue(reader, u8, tag_type)),
79+
hdrs.UINT16 => return @enumFromInt(try unpackIntValue(reader, u16, tag_type)),
80+
hdrs.UINT32 => return @enumFromInt(try unpackIntValue(reader, u32, tag_type)),
81+
hdrs.UINT64 => return @enumFromInt(try unpackIntValue(reader, u64, tag_type)),
82+
else => return maybeUnpackNull(header, T),
10383
}
10484
}
10585

0 commit comments

Comments
 (0)