╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────╮ │17 }; │ │18 │ │19 pub const EventData = union(EventKind) {│ │20 - user: ?struct { │ │20 + user: User, │ │21 + repo: Repo, │ │22 + issue: Issue, │ │23 + │ │24 + pub const User = struct { │ │25 name: []const u8, │ │26 email: []const u8, │ │27 password_hash: []const u8, │ ╰────────────────────────────────────────────╯ ╭─────────────────────────────────╮ │24 - }, │ │25 - repo: ?struct { │ │28 + }; │ │29 + │ │30 + pub const Repo = struct {│ │31 user_id: []const u8, │ │32 name: []const u8, │ │33 enable_issue: bool, │ ╰─────────────────────────────────╯ ╭────────────────────────────────────╮ │29 - }, │ │30 - issue: ?struct { │ │34 + }; │ │35 + │ │36 + pub const Issue = struct { │ │37 title: []const u8, │ │38 description: []const u8,│ │39 tags: []const u8, │ ╰────────────────────────────────────╯ ╭──────────────────────────────╮ │34 - }, │ │40 + }; │ │41 │ │42 pub fn read( │ │43 comptime DB: type,│ ╰──────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │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, .{}), │ │85 + }, │ │86 + .issue => .{ │ │87 + .issue = try std.json.parseFromValueLeaky(Issue, allocator, source, .{}),│ │88 + }, │ │89 + }; │ │90 + } │ │91 + │ │92 fn readBytes( │ │93 comptime DB: type, │ │94 comptime hash_kind: hash.HashKind, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │118 │ │119 pub const Event = struct { │ │120 id: [event_id_size * 2]u8, │ │ 97 - data: EventData, │ │121 + kind: EventKind, │ │122 + data: ?EventData = null, │ │123 + │ │124 + pub fn jsonStringify(self: Event, jw: anytype) !void { │ │125 + try jw.beginObject(); │ │126 + try jw.objectField("id"); │ │127 + try jw.write(self.id); │ │128 + try jw.objectField("kind"); │ │129 + try jw.write(self.kind); │ │130 + 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); │ │139 + } │ │140 + try jw.endObject(); │ │141 + } │ │142 + │ │143 + fn fromString(allocator: std.mem.Allocator, message: []const u8) !Event { │ │144 + const JsonEvent = struct { │ │145 + id: [event_id_size * 2]u8, │ │146 + kind: EventKind, │ │147 + data: ?std.json.Value = null, │ │148 + }; │ │149 + const json_event = try std.json.parseFromSliceLeaky(JsonEvent, allocator, message, .{});│ │150 + return .{ │ │151 + .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, │ │157 + }; │ │158 + } │ │159 }; │ │160 │ │161 pub fn randomId(random: std.Random) [event_id_size]u8 { │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │410 try commit_object.object_reader.seekTo(commit_object.content.commit.message_position); │ │411 const message = try commit_object.object_reader.interface.allocRemaining(arena.allocator(), .unlimited);│ │412 │ │352 - const event = try std.json.parseFromSliceLeaky(Event, arena.allocator(), message, .{}); │ │413 + const event = try Event.fromString(arena.allocator(), message); │ │414 │ │415 // get the id of the current event as bytes │ │416 var current_event_id: [event_id_size]u8 = undefined; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │417 _ = try std.fmt.hexToBytes(&current_event_id, &event.id); │ │418 │ │358 - switch (event.data) { │ │359 - .user => |data_maybe| { │ │419 + switch (event.kind) { │ │420 + .user => { │ │421 const user_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │422 │ │423 const event_id_to_user_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->user"));│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │424 const event_id_to_user = try DB.HashMap(.read_write).init(event_id_to_user_cursor);│ │425 │ │365 - if (data_maybe) |data| { │ │426 + if (event.data) |data| { │ │427 const user_cursor = try event_id_to_user.putCursor(user_key); │ │428 const user_map = try DB.HashMap(.read_write).init(user_cursor); │ │368 - try upsert(DB, repo_opts.hash, user_map, @TypeOf(data), data); │ │429 + try upsert(DB, repo_opts.hash, user_map, EventData.User, data.user); │ │430 } else { │ │431 if (!try event_id_to_user.remove(user_key)) return error.EventNotFound; │ │432 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │435 _ = try user_id_to_repos.remove(user_key); │ │436 } │ │437 }, │ │377 - .repo => |data_maybe| { │ │438 + .repo => { │ │439 const repo_key = hash.hashInt(repo_opts.hash, &current_event_id); │ │440 │ │441 const event_id_to_repo_cursor = try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, "event-id->repo"));│ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯