╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │61 │ │62 // a user repo's path, inside the user's dir │ │63 pub fn userRepoPath(allocator: std.mem.Allocator, users_dir: []const u8, user_id: *const [event_id_size]u8) ![]u8 {│ │64 - return try std.fs.path.join(allocator, &.{ users_dir, &std.fmt.bytesToHex(user_id.*, .lower), "user" }); │ │64 + return try std.Io.Dir.path.join(allocator, &.{ users_dir, &std.fmt.bytesToHex(user_id.*, .lower), "user" }); │ │65 } │ │66 │ │67 // a repo's path, inside its owner's dir │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │68 pub fn repoPath(allocator: std.mem.Allocator, users_dir: []const u8, owner_id: []const u8, repo_id: []const u8) ![]u8 { │ │69 - return try std.fs.path.join(allocator, &.{ users_dir, &std.fmt.bytesToHex(owner_id[0..event_id_size].*, .lower), "repos", &std.fmt.bytesToHex(repo_id[0..event_id_size].*, .lower) }); │ │69 + return try std.Io.Dir.path.join(allocator, &.{ users_dir, &std.fmt.bytesToHex(owner_id[0..event_id_size].*, .lower), "repos", &std.fmt.bytesToHex(repo_id[0..event_id_size].*, .lower) });│ │70 } │ │71 │ │72 // the ids a repo path names, or null for a path `repoPath` didn't build │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │73 pub fn parseRepoPath(users_dir: []const u8, path: []const u8) ?RepoLocation { │ │74 - const repos_dir = std.fs.path.dirname(path) orelse return null; │ │75 - if (!std.mem.eql(u8, std.fs.path.basename(repos_dir), "repos")) return null; │ │76 - const owner_dir = std.fs.path.dirname(repos_dir) orelse return null; │ │77 - if (!std.mem.eql(u8, std.fs.path.dirname(owner_dir) orelse return null, users_dir)) return null; │ │74 + const repos_dir = std.Io.Dir.path.dirname(path) orelse return null; │ │75 + if (!std.mem.eql(u8, std.Io.Dir.path.basename(repos_dir), "repos")) return null; │ │76 + const owner_dir = std.Io.Dir.path.dirname(repos_dir) orelse return null; │ │77 + if (!std.mem.eql(u8, std.Io.Dir.path.dirname(owner_dir) orelse return null, users_dir)) return null;│ │78 return .{ │ │79 - .owner_id = parseEventId(std.fs.path.basename(owner_dir)) catch return null, │ │80 - .repo_id = parseEventId(std.fs.path.basename(path)) catch return null, │ │79 + .owner_id = parseEventId(std.Io.Dir.path.basename(owner_dir)) catch return null, │ │80 + .repo_id = parseEventId(std.Io.Dir.path.basename(path)) catch return null, │ │81 }; │ │82 } │ │83 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │262 // build a `T` by copying its fields, by name, out of `source` │ │263 pub fn project(comptime T: type, source: anytype) T { │ │264 var result: T = undefined; │ │265 - inline for (std.meta.fields(T)) |field| { │ │266 - @field(result, field.name) = @field(source, field.name);│ │265 + inline for (@typeInfo(T).@"struct".field_names) |name| { │ │266 + @field(result, name) = @field(source, name); │ │267 } │ │268 return result; │ │269 } │ ╰─────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │822 json.clearRetainingCapacity(); │ │823 try std.json.Stringify.value(event, .{}, &json.writer); │ │824 if (json.written().len > max_event_size) return error.EventTooLarge; │ │825 - const author = try std.fmt.allocPrint(allocator, "{s} <{s}>", .{ event.author.name, event.author.email });│ │825 + const author = try allocator.print("{s} <{s}>", .{ event.author.name, event.author.email }); │ │826 defer allocator.free(author); │ │827 │ │828 // every event gets a fresh tree │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │831 for (event.tree_entries) |entry| { │ │832 switch (entry) { │ │833 .blob => |blob| { │ │834 - var oid_bytes = [_]u8{0} ** hash.byteLen(repo_opts.hash); │ │834 + var oid_bytes: [hash.byteLen(repo_opts.hash)]u8 = @splat(0); │ │835 try obj.writeObject(repo_kind, repo_opts, state, io, allocator, blob.reader, .{ .kind = .blob, .size = blob.size }, &oid_bytes);│ │836 try tree.addBlobEntry(.{ .content = .{ .unix_permission = 0o644, .object_type = .regular_file } }, blob.name, &oid_bytes); │ │837 }, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1155 const baseline_haxy_moment_cursor = try haxy_moments.getCursor(hash.bytesToInt(repo_opts.hash, &baseline_oid)) orelse return error.CursorNotFound;│ │1156 const baseline_haxy_moment = try DB.HashMap(.read_only).init(baseline_haxy_moment_cursor); │ │1157 │ │1158 - inline for (std.meta.fields(Event)) |field| { │ │1159 - const T = @typeInfo(field.type).optional.child; │ │1158 + inline for (@typeInfo(Event).@"union".field_types) |field_type| { │ │1159 + const T = @typeInfo(field_type).optional.child; │ │1160 try merge(T, DB, repo_opts.hash, allocator, haxy_moment, parent_haxy_moment, baseline_haxy_moment); │ │1161 } │ │1162 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │1353 // created only once a field actually changes │ │1354 var field_oids: ?DB.SortedMap(.read_write) = null; │ │1355 │ │1356 - inline for (std.meta.fields(T)) |field| { │ │1356 + const info = @typeInfo(T).@"struct"; │ │1357 + inline for (info.field_names, info.field_types) |field_name, field_type| { │ │1358 const changed = if (existing_maybe) |existing| │ │1358 - !fieldEqual(field.type, @field(existing, field.name), @field(event, field.name))│ │1359 + !fieldEqual(field_type, @field(existing, field_name), @field(event, field_name))│ │1360 else │ │1361 true; │ │1362 if (changed) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1363 if (field_oids == null) { │ │1364 field_oids = try DB.SortedMap(.read_write).init(try id_to_field_to_oid.putCursor(record_key));│ │1365 } │ │1365 - if (field_oids) |map| try map.put(field.name, .{ .bytes = oid }); │ │1366 + if (field_oids) |map| try map.put(field_name, .{ .bytes = oid }); │ │1367 } │ │1368 } │ │1369 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────╮ │1371 // the whole field list, space separated, is the longest it can get │ │1372 fn conflictedFieldsMaxLen(comptime T: type) usize { │ │1373 var len: usize = 0; │ │1373 - for (std.meta.fields(T)) |field| len += field.name.len + 1; │ │1374 + for (@typeInfo(T).@"struct".field_names) |name| len += name.len + 1;│ │1375 return len; │ │1376 } │ │1377 │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯