Commit c72a9feabe

Josh Wolfe <thejoshwolfe@gmail.com>
2023-07-23 00:52:26
std.json: support parsing json at comptime using FixedBufferAllocator (#16488)
1 parent 2ad1624
Changed files (2)
lib/std/json/static_test.zig
@@ -901,3 +901,28 @@ test "json parse allocate when streaming" {
     try testing.expectEqualSlices(u8, parsed.not_const, "non const string");
     try testing.expectEqualSlices(u8, parsed.is_const, "const string");
 }
+
+test "parse at comptime" {
+    const doc =
+        \\{
+        \\    "vals": {
+        \\        "testing": 1,
+        \\        "production": 42
+        \\    },
+        \\    "uptime": 9999
+        \\}
+    ;
+    const Config = struct {
+        vals: struct { testing: u8, production: u8 },
+        uptime: u64,
+    };
+    const config = comptime x: {
+        var buf: [32]u8 = undefined;
+        var fba = std.heap.FixedBufferAllocator.init(&buf);
+        const res = parseFromSliceLeaky(Config, fba.allocator(), doc, .{});
+        // Assert no error can occur since we are
+        // parsing this JSON at comptime!
+        break :x res catch unreachable;
+    };
+    comptime testing.expectEqual(@as(u64, 9999), config.uptime) catch unreachable;
+}
lib/std/heap.zig
@@ -436,7 +436,7 @@ pub const FixedBufferAllocator = struct {
         const self: *FixedBufferAllocator = @ptrCast(@alignCast(ctx));
         _ = log2_buf_align;
         _ = return_address;
-        assert(self.ownsSlice(buf)); // sanity check
+        assert(@inComptime() or self.ownsSlice(buf));
 
         if (!self.isLastAllocation(buf)) {
             if (new_size > buf.len) return false;
@@ -465,7 +465,7 @@ pub const FixedBufferAllocator = struct {
         const self: *FixedBufferAllocator = @ptrCast(@alignCast(ctx));
         _ = log2_buf_align;
         _ = return_address;
-        assert(self.ownsSlice(buf)); // sanity check
+        assert(@inComptime() or self.ownsSlice(buf));
 
         if (self.isLastAllocation(buf)) {
             self.end_index -= buf.len;