Zig utility library
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Make allocations explicit

IamPyu 17e5bf66 68dd843b

+195 -181
+74 -67
src/StringBuilder.zig
··· 8 8 /// An error that can occur when using a `StringBuilder` 9 9 pub const Error = Allocator.Error; 10 10 11 - allocator: Allocator, 11 + // allocator: Allocator, 12 12 13 13 buf: []u8, 14 14 ptr: usize, ··· 18 18 /// Create a `StringBuilder` 19 19 pub fn init(allocator: Allocator, capacity: usize) Error!Self { 20 20 return Self{ 21 - .allocator = allocator, 21 + // .allocator = allocator, 22 22 .capacity = capacity, 23 23 .ptr = 0, 24 24 .size = 0, ··· 27 27 } 28 28 29 29 /// Deinitialize the string builder 30 - pub fn deinit(self: Self) void { 31 - self.allocator.free(self.buf); 30 + pub fn deinit(self: Self, allocator: Allocator) void { 31 + allocator.free(self.buf); 32 32 } 33 33 34 34 /// Construct the final string using another allocator ··· 39 39 } 40 40 41 41 /// Reserve additional space for the string builder or reduce its size. 42 - pub fn resize(self: *Self, size: usize) Error!void { 42 + pub fn resize(self: *Self, allocator: Allocator, size: usize) Error!void { 43 43 if (size < self.capacity) { 44 - self.buf = try self.allocator.realloc(self.buf, size); 44 + self.buf = try allocator.realloc(self.buf, size); 45 45 self.capacity = size; 46 46 return; 47 47 } 48 48 49 49 const newcap = size * 2; 50 - self.buf = try self.allocator.realloc(self.buf, newcap); 50 + self.buf = try allocator.realloc(self.buf, newcap); 51 51 self.capacity = newcap; 52 52 } 53 53 54 54 /// Append a slice to the string builder 55 - pub fn append(self: *Self, buf: []const u8) Error!void { 55 + pub fn append(self: *Self, allocator: Allocator, buf: []const u8) Error!void { 56 56 const new_size = self.size + buf.len; 57 - try self.resize(new_size); 57 + try self.resize(allocator, new_size); 58 58 59 59 const p = self.buf.ptr + self.ptr; 60 60 @memcpy(p, buf); ··· 64 64 } 65 65 66 66 /// Append a single character to the string builder 67 - pub fn appendChar(self: *Self, c: u8) Error!void { 67 + pub fn appendChar(self: *Self, allocator: Allocator, c: u8) Error!void { 68 68 const new_size = self.size + 1; 69 - try self.resize(new_size); 69 + try self.resize(allocator, new_size); 70 70 71 71 const p = @as(*u8, @ptrCast(self.buf.ptr + self.ptr)); 72 72 p.* = c; ··· 76 76 } 77 77 78 78 /// Append formatted string 79 - pub fn appendFormat(self: *Self, comptime fmt: []const u8, args: anytype) Error!void { 80 - const buf = try std.fmt.allocPrint(self.allocator, fmt, args); 81 - defer self.allocator.free(buf); 82 - try self.append(buf); 79 + pub fn appendFormat(self: *Self, allocator: Allocator, comptime fmt: []const u8, args: anytype) Error!void { 80 + const buf = try std.fmt.allocPrint(allocator, fmt, args); 81 + defer allocator.free(buf); 82 + try self.append(allocator, buf); 83 83 } 84 84 85 85 /// Join this string builder with another 86 - pub fn join(self: *Self, other: *const Self) Error!void { 87 - try self.append(other.written()); 86 + pub fn join(self: *Self, allocator: Allocator, other: *const Self) Error!void { 87 + try self.append(allocator, other.written()); 88 88 } 89 89 90 90 /// Repeat the contents of the string builder `n` times 91 - pub fn repeat(self: *Self, n: usize) Error!void { 91 + pub fn repeat(self: *Self, allocator: Allocator, n: usize) Error!void { 92 92 if (n == 0) 93 93 return; 94 94 95 95 const orig_size = self.size; 96 96 const new_size = orig_size * n; 97 - try self.resize(new_size); 97 + try self.resize(allocator, new_size); 98 98 99 - const tmpbuf = try self.allocator.alloc(u8, orig_size); 100 - defer self.allocator.free(tmpbuf); 101 - @memcpy(tmpbuf, self.buf[0..orig_size]); 99 + const buf = try allocator.alloc(u8, orig_size); 100 + defer allocator.free(buf); 101 + @memcpy(buf, self.buf[0..orig_size]); 102 102 103 103 for (0..n) |_| 104 - try self.append(tmpbuf); 104 + try self.append(allocator, buf); 105 105 } 106 106 107 107 /// Clear the buffer of the string builder ··· 132 132 } 133 133 134 134 test "append" { 135 - var sb = try Self.init(std.testing.allocator, 5); 136 - defer sb.deinit(); 137 - try sb.append("Hello World"); 138 - try sb.appendChar('!'); 135 + const gpa = std.testing.allocator; 136 + var sb = try Self.init(gpa, 5); 137 + defer sb.deinit(gpa); 138 + try sb.append(gpa, "Hello World"); 139 + try sb.appendChar(gpa, '!'); 139 140 140 - const str = try sb.build(std.testing.allocator); 141 - defer std.testing.allocator.free(str); 141 + const str = try sb.build(gpa); 142 + defer gpa.free(str); 142 143 143 144 try std.testing.expectEqualStrings("Hello World!", str); 144 145 } 145 146 146 147 test "join" { 147 - var sb = try Self.init(std.testing.allocator, 5); 148 - defer sb.deinit(); 149 - try sb.append("first StringBuilder,"); 148 + const gpa = std.testing.allocator; 149 + var sb = try Self.init(gpa, 5); 150 + defer sb.deinit(gpa); 151 + try sb.append(gpa, "first StringBuilder,"); 150 152 151 153 { 152 - var tmpsb = try Self.init(std.testing.allocator, 5); 153 - defer tmpsb.deinit(); 154 - try tmpsb.append(" second StringBuilder"); 154 + var tmpsb = try Self.init(gpa, 5); 155 + defer tmpsb.deinit(gpa); 156 + try tmpsb.append(gpa, " second StringBuilder"); 155 157 156 - try sb.join(&tmpsb); 158 + try sb.join(gpa, &tmpsb); 157 159 } 158 160 159 - const str = try sb.build(std.testing.allocator); 160 - defer std.testing.allocator.free(str); 161 + const str = try sb.build(gpa); 162 + defer gpa.free(str); 161 163 162 164 try std.testing.expectEqualStrings("first StringBuilder, second StringBuilder", str); 163 165 } 164 166 165 167 test "repeat" { 166 - var sb = try Self.init(std.testing.allocator, 15); 167 - defer sb.deinit(); 168 - try sb.append("Hello"); 169 - try sb.repeat(4); 168 + const gpa = std.testing.allocator; 169 + var sb = try Self.init(gpa, 15); 170 + defer sb.deinit(gpa); 171 + try sb.append(gpa, "Hello"); 172 + try sb.repeat(gpa, 4); 170 173 171 - const str = try sb.build(std.testing.allocator); 172 - defer std.testing.allocator.free(str); 174 + const str = try sb.build(gpa); 175 + defer gpa.free(str); 173 176 174 177 try std.testing.expectEqualStrings("HelloHelloHelloHelloHello", str); 175 178 } 176 179 177 180 test "clear" { 178 - var sb = try Self.init(std.testing.allocator, 15); 179 - defer sb.deinit(); 180 - try sb.append("123"); 181 - try sb.repeat(4); 181 + const gpa = std.testing.allocator; 182 + var sb = try Self.init(gpa, 15); 183 + defer sb.deinit(gpa); 184 + try sb.append(gpa, "123"); 185 + try sb.repeat(gpa, 4); 182 186 sb.clear(); 183 187 184 - const str = try sb.build(std.testing.allocator); 185 - defer std.testing.allocator.free(str); 188 + const str = try sb.build(gpa); 189 + defer gpa.free(str); 186 190 187 191 try std.testing.expectEqualStrings("", str); 188 192 } 189 193 190 194 test "simple" { 191 - var sb = try Self.init(std.testing.allocator, 15); 192 - defer sb.deinit(); 193 - try sb.append("Hello"); 194 - try sb.append(" World!"); 195 + const gpa = std.testing.allocator; 196 + var sb = try Self.init(gpa, 15); 197 + defer sb.deinit(gpa); 198 + try sb.append(gpa, "Hello"); 199 + try sb.append(gpa, " World!"); 195 200 196 - const str = try sb.build(std.testing.allocator); 197 - defer std.testing.allocator.free(str); 201 + const str = try sb.build(gpa); 202 + defer gpa.free(str); 198 203 199 204 try std.testing.expectEqualStrings("Hello World!", str); 200 205 } 201 206 202 207 test "pop" { 203 - var sb = try Self.init(std.testing.allocator, 15); 204 - defer sb.deinit(); 205 - try sb.append("cool"); 206 - try sb.append("abc"); 208 + const gpa = std.testing.allocator; 209 + var sb = try Self.init(gpa, 15); 210 + defer sb.deinit(gpa); 211 + try sb.append(gpa, "cool"); 212 + try sb.append(gpa, "abc"); 207 213 sb.popMany(3); 208 214 209 - const str = try sb.build(std.testing.allocator); 210 - defer std.testing.allocator.free(str); 215 + const str = try sb.build(gpa); 216 + defer gpa.free(str); 211 217 212 218 try std.testing.expectEqualStrings("cool", str); 213 219 } 214 220 215 221 test "format" { 216 - var sb = try Self.init(std.testing.allocator, 15); 217 - defer sb.deinit(); 222 + const gpa = std.testing.allocator; 223 + var sb = try Self.init(gpa, 15); 224 + defer sb.deinit(gpa); 218 225 219 - try sb.appendFormat("({d},{d})", .{ 43, 69 }); 226 + try sb.appendFormat(gpa, "({d},{d})", .{ 43, 69 }); 220 227 221 - const str = try sb.build(std.testing.allocator); 222 - defer std.testing.allocator.free(str); 228 + const str = try sb.build(gpa); 229 + defer gpa.free(str); 223 230 224 231 try std.testing.expectEqualStrings("(43,69)", str); 225 232 }
+15 -15
src/data/Queue.zig
··· 100 100 const IQueue = Queue(T); 101 101 const NodeList = std.ArrayList(*IQueue.Node); 102 102 103 - allocator: Allocator, 104 103 queue: IQueue, 105 104 nodes: NodeList, 106 105 106 + pub const empty = Self.init(); 107 + 107 108 /// Initialize the `ArrayQueue` 108 - pub fn init(allocator: Allocator) !Self { 109 + pub fn init() !Self { 109 110 return .{ 110 - .allocator = allocator, 111 111 .nodes = .empty, 112 112 .queue = IQueue.init(), 113 113 }; ··· 115 115 116 116 pub fn initCapacity(allocator: Allocator, cap: usize) !Self { 117 117 return .{ 118 - .allocator = allocator, 119 118 .nodes = try NodeList.initCapacity(allocator, cap), 120 119 .queue = IQueue.init(), 121 120 }; 122 121 } 123 122 124 123 /// Deinitialize the queue 125 - pub fn deinit(self: *Self) void { 124 + pub fn deinit(self: *Self, allocator: Allocator) void { 126 125 for (self.nodes.items) |node| { 127 - self.allocator.destroy(node); 126 + allocator.destroy(node); 128 127 } 129 - self.nodes.deinit(self.allocator); 128 + self.nodes.deinit(allocator); 130 129 } 131 130 132 131 /// Enqueue a value 133 - pub fn enqueue(self: *Self, value: T) !void { 134 - try self.nodes.append(self.allocator, try IQueue.Node.initAlloc(self.allocator, value)); 132 + pub fn enqueue(self: *Self, allocator: Allocator, value: T) !void { 133 + try self.nodes.append(allocator, try IQueue.Node.initAlloc(allocator, value)); 135 134 const node = self.nodes.items[self.nodes.items.len - 1]; 136 135 self.queue.enqueue(node); 137 136 } ··· 145 144 146 145 test "queue" { 147 146 const cap = 5000; 148 - var queue = try ArrayQueue(i32).initCapacity(std.testing.allocator, cap); 149 - defer queue.deinit(); 147 + const gpa = std.testing.allocator; 148 + var queue = try ArrayQueue(i32).initCapacity(gpa, cap); 149 + defer queue.deinit(gpa); 150 150 151 - try queue.enqueue(1); 152 - try queue.enqueue(2); 151 + try queue.enqueue(gpa, 1); 152 + try queue.enqueue(gpa, 2); 153 153 _ = queue.dequeue(); 154 - try queue.enqueue(3); 154 + try queue.enqueue(gpa, 3); 155 155 156 156 for (0..cap) |i| { 157 - try queue.enqueue(@intCast(i)); 157 + try queue.enqueue(gpa, @intCast(i)); 158 158 } 159 159 160 160 try std.testing.expectEqual(2, queue.dequeue().?.value);
+1
src/data/RingBuffer.zig
··· 29 29 self.write_index = (self.write_index + 1) % capacity; 30 30 } 31 31 32 + /// Return `true` if the ring buffer is empty 32 33 pub fn isEmpty(self: *const Self) bool { 33 34 return self.read_index == self.write_index; 34 35 }
+33 -31
src/data/SparseSet.zig
··· 11 11 /// The null index, aka "tombstone" 12 12 pub const NULL_INDEX = std.math.maxInt(usize); 13 13 14 - allocator: Allocator, 15 14 sparse: ArrayList(usize), 16 15 dense: ArrayList(T), 17 16 18 17 /// Initialize the sparse set 19 18 pub fn init(allocator: Allocator, size: usize) !Self { 20 19 return Self{ 21 - .allocator = allocator, 22 20 .sparse = try ArrayList(usize).initCapacity(allocator, size), 23 21 .dense = try ArrayList(T).initCapacity(allocator, size), 24 22 }; 25 23 } 26 24 27 25 /// Deinitialize the sparse set 28 - pub fn deinit(self: *Self) void { 29 - self.sparse.deinit(self.allocator); 30 - self.dense.deinit(self.allocator); 26 + pub fn deinit(self: *Self, allocator: Allocator) void { 27 + self.sparse.deinit(allocator); 28 + self.dense.deinit(allocator); 31 29 } 32 30 33 31 /// Insert an element into the sparse set, returning its index 34 - pub fn insert(self: *Self, value: T) !usize { 32 + pub fn insert(self: *Self, allocator: Allocator, value: T) !usize { 35 33 const index = self.sparse.items.len; 36 34 if (index == NULL_INDEX) { 37 35 return NULL_INDEX; 38 36 } 39 - try self.sparse.insert(self.allocator, index, self.dense.items.len); 40 - try self.dense.append(self.allocator, value); 37 + try self.sparse.insert(allocator, index, self.dense.items.len); 38 + try self.dense.append(allocator, value); 41 39 return index; 42 40 } 43 41 ··· 92 90 } 93 91 94 92 test "insert" { 95 - var list = try SparseSet(i32).init(std.testing.allocator, 15); 96 - defer list.deinit(); 93 + const gpa = std.testing.allocator; 94 + var list = try SparseSet(i32).init(gpa, 15); 95 + defer list.deinit(gpa); 97 96 98 - _ = try list.insert(1); 99 - _ = try list.insert(2); 100 - _ = try list.insert(3); 101 - _ = try list.insert(4); 102 - _ = try list.insert(5); 97 + _ = try list.insert(gpa, 1); 98 + _ = try list.insert(gpa, 2); 99 + _ = try list.insert(gpa, 3); 100 + _ = try list.insert(gpa, 4); 101 + _ = try list.insert(gpa, 5); 103 102 104 103 try std.testing.expectEqual(list.len(), 5); 105 104 } 106 105 107 106 test "get" { 108 - var list = try SparseSet(i32).init(std.testing.allocator, 15); 109 - defer list.deinit(); 107 + const gpa = std.testing.allocator; 108 + var list = try SparseSet(i32).init(gpa, 15); 109 + defer list.deinit(gpa); 110 110 111 - _ = try list.insert(1); 112 - const i = try list.insert(2); 113 - _ = try list.insert(3); 111 + _ = try list.insert(gpa, 1); 112 + const i = try list.insert(gpa, 2); 113 + _ = try list.insert(gpa, 3); 114 114 115 115 try std.testing.expectEqual(2, list.get(i).?.*); 116 116 } 117 117 118 118 test "remove" { 119 - var list = try SparseSet(i32).init(std.testing.allocator, 15); 120 - defer list.deinit(); 121 - _ = try list.insert(1); 122 - const i = try list.insert(2); 123 - const g = try list.insert(3); 119 + const gpa = std.testing.allocator; 120 + var list = try SparseSet(i32).init(gpa, 15); 121 + defer list.deinit(gpa); 122 + _ = try list.insert(gpa, 1); 123 + const i = try list.insert(gpa, 2); 124 + const g = try list.insert(gpa, 3); 124 125 const v = list.remove(i); 125 - _ = try list.insert(9); 126 + _ = try list.insert(gpa, 9); 126 127 try std.testing.expectEqual(2, v); 127 128 try std.testing.expectEqual(3, list.get(g).?.*); 128 129 } 129 130 130 131 test "iter" { 131 - var list = try SparseSet([]const u8).init(std.testing.allocator, 15); 132 - defer list.deinit(); 132 + const gpa = std.testing.allocator; 133 + var list = try SparseSet([]const u8).init(gpa, 15); 134 + defer list.deinit(gpa); 133 135 134 - _ = try list.insert("hello world"); 135 - const i = try list.insert("bad message"); 136 + _ = try list.insert(gpa, "hello world"); 137 + const i = try list.insert(gpa, "bad message"); 136 138 _ = list.remove(i); 137 - _ = try list.insert("it's a beautiful day"); 139 + _ = try list.insert(gpa, "it's a beautiful day"); 138 140 139 141 const SliceIterator = @import("../SliceIterator.zig").SliceIterator; 140 142
+35 -33
src/flag.zig
··· 5 5 const std = @import("std"); 6 6 7 7 /// Flag kind 8 + /// 9 + /// `valued` requires the flag is also provided a string value afterwards 10 + /// `boolean` negates a boolean value, usually setting `false` to `true` 8 11 pub const FlagKind = enum { valued, boolean }; 9 12 10 13 /// Flag options 11 14 pub const Flag = struct { 15 + /// Flag name 12 16 name: []const u8, 17 + 18 + /// Flag kind 13 19 kind: FlagKind, 20 + 21 + /// Flag description 14 22 desc: ?[]const u8 = null, 23 + 24 + /// Default boolean value if `kind` is `boolean` 25 + default_bool: bool = false, 15 26 }; 16 27 17 28 /// Argument parse error ··· 27 38 28 39 /// Create an argument parser from `flags` 29 40 pub fn parser(comptime flags: []const Flag) type { 30 - const flag_map = comptime map: { 31 - const N = flags.len; 32 - var flag_map: struct { 33 - names: [N][]const u8, 34 - kinds: [N]FlagKind, 35 - } = .{ 36 - .names = undefined, 37 - .kinds = undefined, 38 - }; 39 - 40 - for (flags, 0..) |flag, i| { 41 - flag_map.names[i] = flag.name; 42 - flag_map.kinds[i] = flag.kind; 43 - } 44 - 45 - break :map flag_map; 46 - }; 47 - 48 41 const FlagsType = type: { 49 42 var fields: []const std.builtin.Type.StructField = &.{}; 50 - for (flag_map.names, flag_map.kinds) |name, kind| { 51 - const field: std.builtin.Type.StructField = switch (kind) { 43 + for (flags) |flag| { 44 + const name = flag.name; 45 + const field: std.builtin.Type.StructField = switch (flag.kind) { 52 46 .boolean => .{ 53 47 .name = name[0..name.len :0], 54 48 .type = bool, 55 - .default_value_ptr = &false, 49 + .default_value_ptr = &flag.default_bool, 56 50 .is_comptime = false, 57 51 .alignment = @alignOf(bool), 58 52 }, ··· 111 105 } 112 106 113 107 var flag_found = false; 114 - inline for (flag_map.names, 0..) |flag_name, j| { 115 - if (std.mem.eql(u8, "-" ++ flag_name, a)) { 108 + inline for (flags) |flag| { 109 + if (std.mem.eql(u8, "-" ++ flag.name, a)) { 116 110 flag_found = true; 117 - switch (flag_map.kinds[j]) { 111 + switch (flag.kind) { 118 112 .boolean => { 119 - @field(out_flags, flag_name) = !@field(out_flags, flag_name); 113 + @field(out_flags, flag.name) = !@field(out_flags, flag.name); 120 114 }, 121 115 .valued => { 122 116 i += 1; 123 117 if (i == args.len) { 124 - if (options.log) 118 + if (options.log) { 125 119 std.log.err( 126 120 "option '{s}' requires an argument but none was provided!", 127 - .{flag_name}, 121 + .{flag.name}, 128 122 ); 123 + } 129 124 return error.MissingValue; 130 125 } 131 126 132 - @field(out_flags, flag_name) = args[i]; 127 + @field(out_flags, flag.name) = args[i]; 133 128 }, 134 129 } 135 130 ··· 138 133 } 139 134 140 135 if (!flag_found) { 141 - if (options.log) 136 + if (options.log) { 142 137 std.log.err("option '{s}' is unknown", .{a}); 138 + } 143 139 return error.UnknownFlag; 144 140 } 145 141 break; ··· 150 146 }; 151 147 } 152 148 153 - test "a" { 154 - const Parser = parser(&.{.{ .name = "name", .kind = .valued }}); 155 - const out = try Parser.parse(&.{ "-name", "Dennis Ritchie" }, .{}); 156 - _ = out; 149 + test "parse" { 150 + const Parser = parser(&.{ 151 + .{ .name = "name", .kind = .valued }, 152 + .{ .name = "age", .kind = .valued }, 153 + }); 154 + const out = try Parser.parse(&.{ "-name", "Dennis Ritchie", "-age", "70" }, .{}); 155 + std.debug.print("{s} is {s} years old on April 1st 2026.\n", .{ 156 + out.flags.name.?, 157 + out.flags.age.?, 158 + }); 157 159 }
+18 -17
src/gamedev/ResourcePath.zig
··· 32 32 return true; 33 33 } 34 34 35 - allocator: Allocator, 36 35 namespace: []u8, 37 36 path: []u8, 38 37 ··· 71 70 @memcpy(path, path_ref); 72 71 73 72 return Self{ 74 - .allocator = allocator, 75 73 .namespace = namespace, 76 74 .path = path, 77 75 }; 78 76 } 79 77 80 78 /// Deinitialize a `ResourcePath` 81 - pub fn deinit(self: *const Self) void { 82 - self.allocator.free(self.namespace); 83 - self.allocator.free(self.path); 79 + pub fn deinit(self: *const Self, allocator: Allocator) void { 80 + allocator.free(self.namespace); 81 + allocator.free(self.path); 84 82 } 85 83 86 84 /// Update the namespace to `new_namespace` 87 - pub fn setNamespace(self: *Self, new_namespace: []const u8) Error!void { 85 + pub fn setNamespace(self: *Self, allocator: Allocator, new_namespace: []const u8) Error!void { 88 86 if (!isValidStr(new_namespace)) { 89 87 return Error.InvalidNamespace; 90 88 } 91 89 92 90 @memset(self.namespace, 0); 93 - self.namespace = try self.allocator.realloc(self.namespace, new_namespace.len); 91 + self.namespace = try allocator.realloc(self.namespace, new_namespace.len); 94 92 @memcpy(self.namespace, new_namespace); 95 93 } 96 94 97 95 /// Update the path to `new_path` 98 - pub fn setPath(self: *Self, new_path: []const u8) Error!void { 96 + pub fn setPath(self: *Self, allocator: Allocator, new_path: []const u8) Error!void { 99 97 if (!isValidStr(new_path)) { 100 98 return Error.InvalidPath; 101 99 } 102 100 103 101 @memset(self.path, 0); 104 - self.path = try self.allocator.realloc(self.path, new_path.len); 102 + self.path = try allocator.realloc(self.path, new_path.len); 105 103 @memcpy(self.path, new_path); 106 104 } 107 105 ··· 120 118 } 121 119 122 120 test "namespace" { 123 - var id = try Self.init(std.testing.allocator, "namespace:path"); 124 - defer id.deinit(); 121 + const gpa = std.testing.allocator; 122 + var id = try Self.init(gpa, "namespace:path"); 123 + defer id.deinit(gpa); 125 124 126 - try id.setPath("different_path"); 125 + try id.setPath(gpa, "different_path"); 127 126 128 127 try std.testing.expectEqualStrings("namespace", id.namespace); 129 128 try std.testing.expectEqualStrings("different_path", id.path); 130 129 } 131 130 132 131 test "invalid_parse" { 132 + const gpa = std.testing.allocator; 133 133 try std.testing.expectError( 134 134 error.InvalidNamespace, 135 - Self.init(std.testing.allocator, ":no_namespace"), 135 + Self.init(gpa, ":no_namespace"), 136 136 ); 137 137 138 138 try std.testing.expectError( 139 139 error.InvalidPath, 140 - Self.init(std.testing.allocator, "no_path:"), 140 + Self.init(gpa, "no_path:"), 141 141 ); 142 142 143 143 try std.testing.expectError( 144 144 error.InvalidPath, 145 - Self.init(std.testing.allocator, "ns:invalid-path"), 145 + Self.init(gpa, "ns:invalid-path"), 146 146 ); 147 147 } 148 148 149 149 test "split" { 150 - var id = try Self.init(std.testing.allocator, "ns:rather/long/path"); 151 - defer id.deinit(); 150 + const gpa = std.testing.allocator; 151 + var id = try Self.init(gpa, "ns:rather/long/path"); 152 + defer id.deinit(gpa); 152 153 153 154 var split = id.splitPath(); 154 155 while (split.next()) |s| {
+19 -18
src/net/packet.zig
··· 1 - //! Generic network packets 1 + //! Generic network packet format 2 2 3 3 const std = @import("std"); 4 4 const Io = std.Io; ··· 18 18 pub fn Packet(T: type) type { 19 19 return struct { 20 20 payload: T, 21 - allocator: Allocator, 22 21 23 22 const Self = @This(); 24 23 ··· 28 27 }; 29 28 30 29 /// Initialize a packet 31 - pub fn init(payload: T, allocator: Allocator) Self { 32 - return Self{ .payload = payload, .allocator = allocator }; 30 + pub fn init(payload: T) Self { 31 + return Self{ .payload = payload }; 33 32 } 34 33 35 34 /// Unwrap the packet, returning the payload ··· 38 37 } 39 38 40 39 /// Serialize the payload to JSON 41 - pub fn serialize(self: *const Self) ![]u8 { 42 - var writer = Io.Writer.Allocating.init(self.allocator); 40 + pub fn serialize(self: *const Self, allocator: Allocator) ![]u8 { 41 + var writer = Io.Writer.Allocating.init(allocator); 43 42 try zon.stringify.serialize(self.payload, .{ .whitespace = false }, &writer.writer); 44 43 45 44 const buf = try writer.toOwnedSlice(); ··· 52 51 } 53 52 54 53 /// Send the packet to a writer 55 - pub fn send(self: *const Self, writer: *Io.Writer) !void { 56 - const packet = try self.serialize(); 57 - defer self.allocator.free(packet); 54 + pub fn send(self: *const Self, allocator: Allocator, writer: *Io.Writer) !void { 55 + const packet = try self.serialize(allocator); 56 + defer allocator.free(packet); 58 57 const size: PacketSize = @intCast(packet.len); 59 58 const header = Header{ .size = size }; 60 59 ··· 64 63 } 65 64 66 65 /// Read a packet from the reader 67 - pub fn chomp(reader: *Io.Reader, allocator: Allocator) ![]u8 { 66 + pub fn chomp(allocator: Allocator, reader: *Io.Reader) ![]u8 { 68 67 const header = try reader.takeStruct(Header, HEADER_ENDIAN); 69 68 const message = try reader.take(header.size); 70 69 const buf = try allocator.alloc(u8, header.size); ··· 76 75 77 76 const Example = struct { x: i32, m: []const u8 }; 78 77 test "serialize" { 79 - var writer = Io.Writer.Allocating.init(std.testing.allocator); 78 + const gpa = std.testing.allocator; 79 + var writer = Io.Writer.Allocating.init(gpa); 80 80 // defer writer.deinit(); 81 81 82 - const packet = Packet(Example).init(.{ .m = "hello", .x = 3 }, std.testing.allocator); 83 - try packet.send(&writer.writer); 82 + const packet = Packet(Example).init(.{ .m = "hello", .x = 3 }); 83 + try packet.send(gpa, &writer.writer); 84 84 85 85 const buf = try writer.toOwnedSlice(); 86 - defer std.testing.allocator.free(buf); 86 + defer gpa.free(buf); 87 87 } 88 88 89 89 test "chomp" { 90 - const packet = Packet(Example).init(.{ .m = "hello", .x = 3 }, std.testing.allocator); 90 + const gpa = std.testing.allocator; 91 + const packet = Packet(Example).init(.{ .m = "hello", .x = 3 }); 91 92 92 93 const FILE_NAME = "packet-chomp-test"; 93 94 var file = try std.fs.cwd().createFile(FILE_NAME, .{ .read = true }); 94 95 95 96 var wbuf: [1024]u8 = undefined; 96 97 var writer = file.writer(&wbuf); 97 - try packet.send(&writer.interface); 98 + try packet.send(gpa, &writer.interface); 98 99 99 100 var rbuf: [1024]u8 = undefined; 100 101 var reader = file.reader(&rbuf); 101 - const output = try Packet(Example).chomp(&reader.interface, std.testing.allocator); 102 - defer std.testing.allocator.free(output); 102 + const output = try Packet(Example).chomp(gpa, &reader.interface); 103 + defer gpa.free(output); 103 104 104 105 try std.testing.expectEqualSlices(u8, 105 106 \\.{.x=3,.m="hello"}