╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │67 .description = try readBytes(DB, hash_kind, allocator, map, "description"),│ │68 .tags = try readBytes(DB, hash_kind, allocator, map, "tags"), │ │69 }, │ │70 - }, │ │71 - }; │ │72 - } │ │73 - │ │74 - pub fn fromJson( │ │75 - allocator: std.mem.Allocator, │ │76 - kind: EventKind, │ │77 - source: std.json.Value, │ │78 - ) !EventData { │ │79 - return switch (kind) { │ │80 - .user => .{ │ │81 - .user = try std.json.parseFromValueLeaky(User, allocator, source, .{}), │ │82 - }, │ │83 - .repo => .{ │ │84 - .repo = try std.json.parseFromValueLeaky(Repo, allocator, source, .{}), │ │70 }, │ │86 - .issue => .{ │ │87 - .issue = try std.json.parseFromValueLeaky(Issue, allocator, source, .{}), │ │88 - }, │ │71 }; │ │72 } │ │73 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │100 │ │101 pub const Event = struct { │ │102 id: [event_id_size * 2]u8, │ │121 - kind: EventKind, │ │122 - data: ?EventData = null, │ │103 + data: MaybeEventData, │ │104 + │ │105 + pub const MaybeEventData = union(EventKind) { │ │106 + user: ?EventData.User, │ │107 + repo: ?EventData.Repo, │ │108 + issue: ?EventData.Issue, │ │109 + │ │110 + fn fromJson( │ │111 + allocator: std.mem.Allocator, │ │112 + kind: EventKind, │ │113 + value_maybe: ?std.json.Value, │ │114 + ) !MaybeEventData { │ │115 + return switch (kind) { │ │116 + .user => .{ │ │117 + .user = if (value_maybe) |value| try std.json.parseFromValueLeaky(EventData.User, allocator, value, .{}) else null, │ │118 + }, │ │119 + .repo => .{ │ │120 + .repo = if (value_maybe) |value| try std.json.parseFromValueLeaky(EventData.Repo, allocator, value, .{}) else null, │ │121 + }, │ │122 + .issue => .{ │ │123 + .issue = if (value_maybe) |value| try std.json.parseFromValueLeaky(EventData.Issue, allocator, value, .{}) else null,│ │124 + }, │ │125 + }; │ │126 + } │ │127 + }; │ │128 │ │129 pub fn jsonStringify(self: Event, jw: anytype) !void { │ │130 try jw.beginObject(); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────╮ │131 try jw.objectField("id"); │ │132 try jw.write(self.id); │ │133 try jw.objectField("kind"); │ │129 - try jw.write(self.kind); │ │134 + try jw.write(@tagName(self.data)); │ │135 try jw.objectField("data"); │ │131 - if (self.data) |data_maybe| { │ │132 - switch (data_maybe) { │ │133 - .user => |data| try jw.write(data), │ │134 - .repo => |data| try jw.write(data), │ │135 - .issue => |data| try jw.write(data), │ │136 - } │ │137 - } else { │ │138 - try jw.write(null); │ │136 + switch (self.data) { │ │137 + inline else => |data_maybe| try jw.write(data_maybe),│ │138 } │ │139 try jw.endObject(); │ │140 } │ ╰──────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │148 const json_event = try std.json.parseFromSliceLeaky(JsonEvent, allocator, message, .{});│ │149 return .{ │ │150 .id = json_event.id, │ │152 - .kind = json_event.kind, │ │153 - .data = if (json_event.data) |data| │ │154 - try EventData.fromJson(allocator, json_event.kind, data) │ │155 - else │ │156 - null, │ │151 + .data = try MaybeEventData.fromJson(allocator, json_event.kind, json_event.data), │ │152 }; │ │153 } │ │154 }; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │411 var current_event_id: [event_id_size]u8 = undefined; │ │412 _ = try std.fmt.hexToBytes(&current_event_id, &event.id); │ │413 │ │419 - switch (event.kind) { │ │420 - .user => { │ │414 + switch (event.data) { │ │415 + .user => |user_data_maybe| { │ │416 const user_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │417 │ │418 const event_id_to_user_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->user"));│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │419 const event_id_to_user = try DB.HashMap(.read_write).init(event_id_to_user_cursor);│ │420 │ │426 - if (event.data) |data| { │ │421 + if (user_data_maybe) |user_data| { │ │422 const user_cursor = try event_id_to_user.putCursor(user_key); │ │423 const user_map = try DB.HashMap(.read_write).init(user_cursor); │ │429 - try upsert(DB, repo_opts.hash, user_map, EventData.User, data.user); │ │424 + try upsert(DB, repo_opts.hash, user_map, EventData.User, user_data); │ │425 } else { │ │426 if (!try event_id_to_user.remove(user_key)) return error.EventNotFound; │ │427 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │430 _ = try user_id_to_repos.remove(user_key); │ │431 } │ │432 }, │ │438 - .repo => { │ │433 + .repo => |repo_data_maybe| { │ │434 const repo_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │435 │ │436 const event_id_to_repo_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->repo"));│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │437 const event_id_to_repo = try DB.HashMap(.read_write).init(event_id_to_repo_cursor); │ │438 │ │444 - if (event.data) |data| { │ │439 + if (repo_data_maybe) |repo_data| { │ │440 const repo_cursor = try event_id_to_repo.putCursor(repo_key); │ │441 const repo_map = try DB.HashMap(.read_write).init(repo_cursor); │ │447 - try upsert(DB, repo_opts.hash, repo_map, EventData.Repo, data.repo); │ │442 + try upsert(DB, repo_opts.hash, repo_map, EventData.Repo, repo_data); │ │443 │ │444 const user_id_to_repos_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "user-id->repos"));│ │445 const user_id_to_repos = try DB.HashMap(.read_write).init(user_id_to_repos_cursor); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │446 │ │452 - const user_repos_cursor = try user_id_to_repos.putCursor(hash.hashInt(repo_opts.hash, data.repo.user_id));│ │447 + const user_repos_cursor = try user_id_to_repos.putCursor(hash.hashInt(repo_opts.hash, repo_data.user_id));│ │448 const user_repos = try DB.CountedHashSet(.read_write).init(user_repos_cursor); │ │449 try user_repos.put(repo_key, .{ .bytes = &current_event_id }); │ │450 } else { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │464 if (!try event_id_to_repo.remove(repo_key)) return error.EventNotFound; │ │465 } │ │466 }, │ │472 - .issue => { │ │467 + .issue => |issue_data_maybe| { │ │468 const issue_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │469 │ │470 const event_id_to_issue_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->issue"));│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯