╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭────────────────────────────────────╮ │18 issue, │ │19 }; │ │20 │ │21 -pub const Event = struct { │ │21 +pub const EventWithId = struct {│ │22 id: [event_id_size * 2]u8, │ │23 - data: union(EventKind) { │ │23 + event: union(EventKind) { │ │24 user: ?User, │ │25 repo: ?Repo, │ │26 issue: ?Issue, │ ╰────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────╮ │27 }, │ │28 │ │29 - pub fn jsonStringify(self: Event, jw: anytype) !void { │ │29 + pub fn jsonStringify(self: EventWithId, jw: anytype) !void {│ │30 try jw.beginObject(); │ │31 try jw.objectField("id"); │ │32 try jw.write(self.id); │ ╰────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────╮ │33 try jw.objectField("kind"); │ │34 - try jw.write(@tagName(self.data)); │ │34 + try jw.write(@tagName(self.event)); │ │35 try jw.objectField("data"); │ │36 - switch (self.data) { │ │37 - inline else => |data_maybe| try jw.write(data_maybe), │ │36 + switch (self.event) { │ │37 + inline else => |event_maybe| try jw.write(event_maybe),│ │38 } │ │39 try jw.endObject(); │ │40 } │ ╰───────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │41 │ │42 - fn fromString(arena: *std.heap.ArenaAllocator, message: []const u8) !Event { │ │42 + fn fromString(arena: *std.heap.ArenaAllocator, message: []const u8) !EventWithId {│ │43 const JsonEvent = struct { │ │44 id: [event_id_size * 2]u8, │ │45 kind: EventKind, │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │48 const json_event = try std.json.parseFromSliceLeaky(JsonEvent, arena.allocator(), message, .{}); │ │49 return .{ │ │50 .id = json_event.id, │ │51 - .data = switch (json_event.kind) { │ │51 + .event = switch (json_event.kind) { │ │52 .user => .{ │ │53 - .user = if (json_event.data) |value| try std.json.parseFromValueLeaky(User, arena.allocator(), value, .{}) else null, │ │53 + .user = if (json_event.data) |value| │ │54 + try std.json.parseFromValueLeaky(User, arena.allocator(), value, .{}) │ │55 + else │ │56 + null, │ │57 }, │ │58 .repo => .{ │ │56 - .repo = if (json_event.data) |value| try std.json.parseFromValueLeaky(Repo, arena.allocator(), value, .{}) else null, │ │59 + .repo = if (json_event.data) |value| │ │60 + try std.json.parseFromValueLeaky(Repo, arena.allocator(), value, .{}) │ │61 + else │ │62 + null, │ │63 }, │ │64 .issue => .{ │ │59 - .issue = if (json_event.data) |value| try std.json.parseFromValueLeaky(Issue, arena.allocator(), value, .{}) else null,│ │65 + .issue = if (json_event.data) |value| │ │66 + try std.json.parseFromValueLeaky(Issue, arena.allocator(), value, .{}) │ │67 + else │ │68 + null, │ │69 }, │ │70 }, │ │71 }; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │294 try commit_object.object_reader.seekTo(commit_object.content.commit.message_position); │ │295 const message = try commit_object.object_reader.interface.allocRemaining(arena.allocator(), .unlimited);│ │296 │ │288 - const event = try Event.fromString(&arena, message); │ │297 + const event_with_id = try EventWithId.fromString(&arena, message); │ │298 │ │299 // get the id of the current event as bytes │ │300 var current_event_id: [event_id_size]u8 = undefined; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │292 - _ = try std.fmt.hexToBytes(&current_event_id, &event.id); │ │293 - │ │294 - switch (event.data) { │ │295 - .user => |user_data_maybe| { │ │296 - const user_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │297 - │ │298 - const event_id_to_user_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->user")); │ │299 - const event_id_to_user = try DB.HashMap(.read_write).init(event_id_to_user_cursor); │ │300 - │ │301 - if (user_data_maybe) |user_data| { │ │302 - const user_cursor = try event_id_to_user.putCursor(user_key); │ │303 - const user = try DB.HashMap(.read_write).init(user_cursor); │ │304 - try upsert(User, DB, repo_opts.hash, user, user_data); │ │305 - } else { │ │306 - if (!try event_id_to_user.remove(user_key)) return error.EventNotFound; │ │301 + _ = try std.fmt.hexToBytes(&current_event_id, &event_with_id.id); │ │302 │ │308 - const user_id_to_repos_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "user-id->repos")); │ │309 - const user_id_to_repos = try DB.HashMap(.read_write).init(user_id_to_repos_cursor); │ │310 - _ = try user_id_to_repos.remove(user_key); │ │311 - } │ │312 - }, │ │313 - .repo => |repo_data_maybe| { │ │314 - const repo_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │315 - │ │316 - const event_id_to_repo_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->repo")); │ │317 - const event_id_to_repo = try DB.HashMap(.read_write).init(event_id_to_repo_cursor); │ │318 - │ │319 - if (repo_data_maybe) |repo_data| { │ │320 - const repo_cursor = try event_id_to_repo.putCursor(repo_key); │ │321 - const repo = try DB.HashMap(.read_write).init(repo_cursor); │ │322 - try upsert(Repo, DB, repo_opts.hash, repo, repo_data); │ │323 - │ │324 - const user_id_to_repos_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "user-id->repos")); │ │325 - const user_id_to_repos = try DB.HashMap(.read_write).init(user_id_to_repos_cursor); │ │326 - │ │327 - const user_repos_cursor = try user_id_to_repos.putCursor(hash.hashInt(repo_opts.hash, repo_data.user_id)); │ │328 - const user_repos = try DB.CountedHashSet(.read_write).init(user_repos_cursor); │ │329 - try user_repos.put(repo_key, .{ .bytes = &current_event_id }); │ │330 - } else { │ │331 - if (try event_id_to_repo.getCursor(repo_key)) |existing_repo_cursor| { │ │332 - const existing_repo = try DB.HashMap(.read_only).init(existing_repo_cursor); │ │333 - const existing_repo_data = try read(Repo, DB, repo_opts.hash, &arena, existing_repo); │ │334 - │ │335 - const user_id_to_repos_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "user-id->repos"));│ │336 - const user_id_to_repos = try DB.HashMap(.read_write).init(user_id_to_repos_cursor); │ │337 - │ │338 - const user_key = hash.hashInt(repo_opts.hash, existing_repo_data.user_id); │ │339 - const user_repos_cursor = try user_id_to_repos.putCursor(user_key); │ │340 - const user_repos = try DB.CountedHashSet(.read_write).init(user_repos_cursor); │ │341 - _ = try user_repos.remove(repo_key); │ │342 - } │ │343 - if (!try event_id_to_repo.remove(repo_key)) return error.EventNotFound; │ │344 - } │ │345 - }, │ │346 - .issue => |issue_data_maybe| { │ │347 - const issue_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │348 - │ │349 - const event_id_to_issue_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->issue")); │ │350 - const event_id_to_issue = try DB.HashMap(.read_write).init(event_id_to_issue_cursor); │ │351 - │ │352 - if (issue_data_maybe) |issue_data| { │ │353 - const issue_cursor = try event_id_to_issue.putCursor(issue_key); │ │354 - const issue = try DB.HashMap(.read_write).init(issue_cursor); │ │355 - try upsert(Issue, DB, repo_opts.hash, issue, issue_data); │ │356 - } else { │ │357 - if (!try event_id_to_issue.remove(issue_key)) return error.EventNotFound; │ │358 - } │ │359 - }, │ │303 + switch (event_with_id.event) { │ │304 + .user => |event_maybe| try User.consume(DB, repo_opts.hash, haxy_moment, &current_event_id, event_maybe), │ │305 + .repo => |event_maybe| try Repo.consume(DB, repo_opts.hash, haxy_moment, &current_event_id, event_maybe, &arena), │ │306 + .issue => |event_maybe| try Issue.consume(DB, repo_opts.hash, haxy_moment, &current_event_id, event_maybe), │ │307 } │ │308 } │ │309 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────╮ │330 arena: *std.heap.ArenaAllocator, │ │331 map: DB.HashMap(.read_only), │ │332 ) !T { │ │386 - var value: T = undefined; │ │333 + var event: T = undefined; │ │334 │ │335 switch (@typeInfo(T)) { │ │336 .@"struct" => |struct_info| {│ ╰──────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │338 switch (@typeInfo(field.type)) { │ │339 .pointer => |pointer_info| { │ │340 if (pointer_info.size == .slice and pointer_info.child == u8 and pointer_info.is_const) { │ │394 - @field(value, field.name) = try readBytes(DB, hash_kind, arena.allocator(), map, field.name);│ │341 + @field(event, field.name) = try readBytes(DB, hash_kind, arena.allocator(), map, field.name);│ │342 } else { │ │343 @compileError("unsupported read field type: " ++ @typeName(field.type)); │ │344 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │347 if (array_info.child == u8) { │ │348 const bytes = try readBytes(DB, hash_kind, arena.allocator(), map, field.name);│ │349 if (bytes.len != array_info.len) return error.InvalidByteArrayLength; │ │403 - @memcpy(@field(value, field.name)[0..], bytes); │ │350 + @memcpy(@field(event, field.name)[0..], bytes); │ │351 } else { │ │352 @compileError("unsupported read field type: " ++ @typeName(field.type)); │ │353 } │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯