From d047ab036922403b8d7af19189161214120ac757 Mon Sep 17 00:00:00 2001 From: Gota7 Date: Mon, 22 Dec 2025 21:26:58 -0500 Subject: [PATCH 1/3] Fix serialization of vectors bug --- src/Writer.zig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Writer.zig b/src/Writer.zig index 891f14c..d4bcc8e 100644 --- a/src/Writer.zig +++ b/src/Writer.zig @@ -357,7 +357,7 @@ pub fn writeAnyExplicit(self: *Writer, comptime T: type, data: T) Error!void { .vector => |vector_info| { try self.startArray(); var i: usize = 0; - inline while (i < vector_info.len) : (i += 1) { + while (i < vector_info.len) : (i += 1) { try self.writeAnyExplicit(@TypeOf(data[i]), data[i]); } try self.endContainer(); From 4e342a4fdb5c5739774ef02b2a54c758e476928c Mon Sep 17 00:00:00 2001 From: Gota7 Date: Wed, 24 Dec 2025 12:16:28 -0500 Subject: [PATCH 2/3] Produce and consume void values --- src/Inspect.zig | 1 + src/Reader.zig | 45 ++++++++++++++++++++++++--------------------- src/Writer.zig | 4 ++-- src/common.zig | 1 + 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/src/Inspect.zig b/src/Inspect.zig index 2a8e07a..cd25794 100644 --- a/src/Inspect.zig +++ b/src/Inspect.zig @@ -185,6 +185,7 @@ pub fn Inspect(comptime limits: ReadLimits) type { .varIntBytes => try self.writeString(val.varIntBytes), .smallBytes => try self.writeString(val.smallBytes), .null => try w.writeAll("null"), + .void => try w.writeAll("void"), .containerEnd => try w.writeAll("END"), .smallIntPositive => try w.print("{d}", .{val.smallIntPositive}), .smallIntNegative => try w.print("-{d}", .{val.smallIntNegative}), diff --git a/src/Reader.zig b/src/Reader.zig index bfd2d49..768e543 100644 --- a/src/Reader.zig +++ b/src/Reader.zig @@ -208,6 +208,9 @@ pub fn Reader(comptime limits: ReadLimits) type { .bool => { return .{ .bool = (decoded_tag.data != 0) }; }, + .void => { + return .{ .void = undefined }; + }, .varIntBytes => { const len = try self.readBytesLength(.varIntBytes, decoded_tag.data); if (len > self.bytes.len - self.pos) return error.UnexpectedEof; @@ -325,7 +328,7 @@ pub fn Reader(comptime limits: ReadLimits) type { .f16 => self.pos += 2, .i16, .u16 => self.pos += 2, .i8, .u8 => self.pos += 1, - .null, .bool => {}, + .null, .bool, .void => {}, .smallIntPositive, .smallIntNegative, .smallUint => {}, // Variable length integers @@ -532,11 +535,11 @@ pub fn Reader(comptime limits: ReadLimits) type { const root_peek = try self.peekTag(); - if (root_peek.tag != .object and root_peek.tag != .array) { - if (remaining > 0) { - var has_empty = false; - for (queries) |q| { - if (!q.resolved and q.path.len == 0) { + if (root_peek.tag != .object and root_peek.tag != .array) { + if (remaining > 0) { + var has_empty = false; + for (queries) |q| { + if (!q.resolved and q.path.len == 0) { has_empty = true; break; } @@ -551,8 +554,8 @@ pub fn Reader(comptime limits: ReadLimits) type { remaining -= 1; } } - } } + } if (queries.len > 1) { const LessIdx = struct { @@ -878,20 +881,20 @@ pub fn Reader(comptime limits: ReadLimits) type { const off = index * elem_size; const chunk = ta.bytes[off..][0..elem_size]; - return switch (ta.elem) { - .u8 => .{ .u8 = chunk[0] }, - .i8 => .{ .i8 = @bitCast(chunk[0]) }, - .u16 => .{ .u16 = std.mem.readInt(u16, chunk[0..2], .little) }, - .i16 => .{ .i16 = std.mem.readInt(i16, chunk[0..2], .little) }, - .u32 => .{ .u32 = std.mem.readInt(u32, chunk[0..4], .little) }, - .i32 => .{ .i32 = std.mem.readInt(i32, chunk[0..4], .little) }, - .u64 => .{ .u64 = std.mem.readInt(u64, chunk[0..8], .little) }, - .i64 => .{ .i64 = std.mem.readInt(i64, chunk[0..8], .little) }, - .f32 => .{ .f32 = @bitCast(std.mem.readInt(u32, chunk[0..4], .little)) }, - .f64 => .{ .f64 = @bitCast(std.mem.readInt(u64, chunk[0..8], .little)) }, - .f16 => .{ .f16 = @bitCast(std.mem.readInt(u16, chunk[0..2], .little)) }, - }; - } + return switch (ta.elem) { + .u8 => .{ .u8 = chunk[0] }, + .i8 => .{ .i8 = @bitCast(chunk[0]) }, + .u16 => .{ .u16 = std.mem.readInt(u16, chunk[0..2], .little) }, + .i16 => .{ .i16 = std.mem.readInt(i16, chunk[0..2], .little) }, + .u32 => .{ .u32 = std.mem.readInt(u32, chunk[0..4], .little) }, + .i32 => .{ .i32 = std.mem.readInt(i32, chunk[0..4], .little) }, + .u64 => .{ .u64 = std.mem.readInt(u64, chunk[0..8], .little) }, + .i64 => .{ .i64 = std.mem.readInt(i64, chunk[0..8], .little) }, + .f32 => .{ .f32 = @bitCast(std.mem.readInt(u32, chunk[0..4], .little)) }, + .f64 => .{ .f64 = @bitCast(std.mem.readInt(u64, chunk[0..8], .little)) }, + .f16 => .{ .f16 = @bitCast(std.mem.readInt(u16, chunk[0..2], .little)) }, + }; + } /// Reads a value at a given path. Path format: "key", "key.nested", "array[0]", "obj.arr[2].name" /// Returns null if the path doesn't exist or points to an incompatible type. diff --git a/src/Writer.zig b/src/Writer.zig index d4bcc8e..a276229 100644 --- a/src/Writer.zig +++ b/src/Writer.zig @@ -139,7 +139,7 @@ pub fn write(self: *Writer, data: common.Value, comptime tag: std.meta.Tag(commo .f64 => try w.writeInt(u64, @bitCast(data.f64), .little), .f32 => try w.writeInt(u32, @bitCast(data.f32), .little), .f16 => try w.writeInt(u16, @bitCast(data.f16), .little), - .object, .array, .containerEnd, .null => {}, + .object, .array, .containerEnd, .null, .void => {}, .bytes => { try w.writeInt(u64, data.bytes.len, .little); try w.writeAll(data.bytes); @@ -377,7 +377,7 @@ pub fn writeAnyExplicit(self: *Writer, comptime T: type, data: T) Error!void { @compileError("bufzilla: untagged unions are not supported"); } }, - .void => {}, + .void => try self.write(common.Value{ .void = undefined }, .void), else => { @compileError("bufzilla: unsupported data type: " ++ @typeName(T)); }, diff --git a/src/common.zig b/src/common.zig index 4cda86a..0521d36 100644 --- a/src/common.zig +++ b/src/common.zig @@ -148,6 +148,7 @@ pub const Value = union(enum) { // Simple types bool: bool, null: void, + void: void, // Small signed integers where magnitude (0..7) is stored in the tag data bits. // For negative small ints, magnitude 0 is invalid (no negative zero). From 1e525cd982d16a057134b6771b427b6e47c71022 Mon Sep 17 00:00:00 2001 From: Gota7 Date: Wed, 24 Dec 2025 15:24:23 -0500 Subject: [PATCH 3/3] Allow writing enums and union tags --- src/Writer.zig | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Writer.zig b/src/Writer.zig index a276229..aca117e 100644 --- a/src/Writer.zig +++ b/src/Writer.zig @@ -362,6 +362,15 @@ pub fn writeAnyExplicit(self: *Writer, comptime T: type, data: T) Error!void { } try self.endContainer(); }, + .@"enum" => |enum_info| { + inline for (enum_info.fields) |field| { + const field_tag = @field(T, field.name); + if (field_tag == data) { + try self.writeAnyExplicit(@TypeOf(field.name), field.name); + break; + } + } + }, .@"union" => |union_info| { if (union_info.tag_type) |TT| { const tag: TT = data; @@ -369,6 +378,7 @@ pub fn writeAnyExplicit(self: *Writer, comptime T: type, data: T) Error!void { const field_tag = @field(TT, field.name); if (field_tag == tag) { const field_value = @field(data, field.name); + try self.writeAnyExplicit(@TypeOf(field.name), field.name); try self.writeAnyExplicit(@TypeOf(field_value), field_value); break; }