prefect server in zig
1# zig 0.15 patterns
2
3notes from working with zig 0.15.2 in this codebase.
4
5## ArrayListUnmanaged vs ArrayList
6
7in zig 0.15, use `ArrayListUnmanaged` with explicit allocator per-method instead of `ArrayList.init(alloc)`:
8
9```zig
10// prefer this pattern
11var results = std.ArrayListUnmanaged(MyType){};
12try results.append(alloc, item);
13defer results.deinit(alloc);
14return results.toOwnedSlice(alloc);
15
16// NOT this (old pattern)
17var results = std.ArrayList(MyType).init(alloc); // error: no member 'init'
18```
19
20this matches the pattern used throughout the codebase (see `db/*.zig`).
21
22## pg.zig strict type checking
23
24postgres driver (`pg.zig`) is strict about column types:
25
26- `INTEGER` / `INT4` → must use `i32` via `row.getInt(col)`
27- `BIGINT` / `INT8` → must use `i64` via `row.getBigInt(col)`
28
29our backend.zig abstraction:
30```zig
31pub fn int(self: Row, col: usize) i64 {
32 // for INTEGER columns
33 return switch (self) {
34 .sqlite => |r| r.int(col),
35 .postgres => |r| r.getInt(col), // returns i32, coerced to i64
36 };
37}
38
39pub fn bigint(self: Row, col: usize) i64 {
40 // for BIGINT columns
41 return switch (self) {
42 .sqlite => |r| r.int(col),
43 .postgres => |r| r.getBigInt(col), // returns i64
44 };
45}
46```
47
48## buffer allocation: stack first, heap fallback
49
50for variable-size data, try stack buffer first, fall back to heap for large data:
51
52```zig
53var heap_buf: ?[]u8 = null;
54defer if (heap_buf) |hb| alloc.free(hb);
55
56const result = blk: {
57 // try 64KB stack buffer first
58 var stack_buf: [65536]u8 = undefined;
59 break :blk doWork(&stack_buf, data) catch |err| {
60 if (err == error.NoSpaceLeft and data.len > 60000) {
61 // large data - allocate on heap
62 heap_buf = try alloc.alloc(u8, data.len + 1024);
63 break :blk try doWork(heap_buf.?, data);
64 }
65 return err;
66 };
67};
68```
69
70this avoids heap allocation for common cases while handling edge cases.
71
72## function pointer types with slice parameters
73
74when accepting buffers, use `[]u8` slice instead of pointer-to-array:
75
76```zig
77// flexible - works with stack and heap buffers
78fn formatJson(buf: []u8, data: []const u8) ![]const u8 {
79 return std.fmt.bufPrint(buf, ...);
80}
81
82// usage with stack buffer
83var stack_buf: [65536]u8 = undefined;
84_ = try formatJson(&stack_buf, data);
85
86// usage with heap buffer
87const heap_buf = try alloc.alloc(u8, size);
88_ = try formatJson(heap_buf, data);
89```