polls on atproto pollz.waow.tech
atproto zig
at main 126 lines 2.9 kB view raw view rendered
1# zig 0.15 notes 2 3reference for zig 0.15 patterns used in the backend. 4 5## breaking changes from 0.14 6 7### json.stringify → json.fmt 8```zig 9// old: json.stringify(value, .{}, writer); 10// new: use json.fmt formatter 11try buffer.print(allocator, "{f}", .{json.fmt(value, .{})}); 12``` 13 14### std.ArrayList is unmanaged by default 15```zig 16// old 0.14 style: 17var list = std.ArrayList(u8).init(allocator); 18try list.appendSlice("hello"); 19list.deinit(); 20 21// new 0.15 style: 22var list: std.ArrayList(u8) = .{}; 23try list.appendSlice(allocator, "hello"); 24list.deinit(allocator); 25``` 26 27### std.time.sleep removed 28```zig 29// use posix.nanosleep instead 30std.posix.nanosleep(seconds, nanoseconds); 31``` 32 33### std.Uri.percentDecode → percentDecodeInPlace 34```zig 35// copy to mutable buffer first, then decode in place 36const uri_buf = try alloc.dupe(u8, uri_encoded); 37const uri = std.Uri.percentDecodeInPlace(uri_buf); 38``` 39 40## http server patterns 41 42### net.Stream → http.Server 43```zig 44var read_buffer: [8192]u8 = undefined; 45var write_buffer: [8192]u8 = undefined; 46 47var reader = conn.stream.reader(&read_buffer); 48var writer = conn.stream.writer(&write_buffer); 49 50var server = http.Server.init(reader.interface(), &writer.interface); 51``` 52 53### responding to requests 54```zig 55try request.respond(body, .{ 56 .status = .ok, 57 .extra_headers = &.{ 58 .{ .name = "content-type", .value = "application/json" }, 59 }, 60}); 61``` 62 63## websocket client (karlseguin/websocket.zig) 64 65```zig 66const websocket = @import("websocket"); 67 68var client = try websocket.Client.init(allocator, .{ 69 .host = "example.com", 70 .port = 443, 71 .tls = true, 72}); 73defer client.deinit(); 74 75// Host header must be provided manually 76client.handshake("/path", .{ .headers = "Host: example.com\r\n" }) catch |err| { 77 // handle error 78}; 79 80// handler must have serverMessage(self, data) function 81var handler = MyHandler{}; 82try client.readLoop(&handler); 83``` 84 85## sqlite patterns (zqlite) 86 87### prepared statements with bind 88```zig 89var stmt = conn.prepare("SELECT * FROM votes WHERE uri = ?") catch return; 90defer stmt.deinit(); 91 92const row = stmt.bind(.{uri}).step() catch return; 93if (row) |r| { 94 const subject = r[0].?.text; 95 // ... 96} 97``` 98 99### upsert with ON CONFLICT 100```zig 101conn.exec( 102 \\INSERT INTO votes (uri, subject, option, voter, created_at) 103 \\VALUES (?, ?, ?, ?, ?) 104 \\ON CONFLICT(subject, voter) DO UPDATE SET 105 \\ uri = excluded.uri, 106 \\ option = excluded.option, 107 \\ created_at = excluded.created_at 108 \\WHERE excluded.created_at > votes.created_at OR votes.created_at IS NULL 109, .{ uri, subject, option, voter, created_at }) catch |err| { 110 // handle error 111}; 112``` 113 114## build.zig.zon 115 116```zig 117.{ 118 .name = .pollz, 119 .version = "0.0.0", 120 .fingerprint = 0x..., // required in 0.15 121 .dependencies = .{ 122 .zqlite = .{ ... }, 123 .websocket = .{ ... }, 124 }, 125} 126```