╭ changed ──────────╮ │src/event/Patch.zig│ ╰───────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │35 std.mem.eql(u8, record.patch_oid, self.squash_oid) and │ │36 std.mem.eql(u8, record.event.source_oid, self.source_oid); │ │37 } │ │38 +}; │ │39 │ │39 - pub fn includesOid(self: Revision, oid: []const u8) bool { │ │40 - return std.mem.eql(u8, oid, self.source_oid) or std.mem.eql(u8, oid, self.squash_oid);│ │41 - } │ │42 -}; │ │40 +pub const MergeRevision = enum { squash, source }; │ │41 │ │42 pub const Record = struct { │ │43 event: Self, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │64 pub const Status = union(StatusKind) { │ │65 open, │ │66 closed, │ │69 - merged: []const u8, │ │67 + merged: Merged, │ │68 │ │71 - pub const max_encoded_len = "merged ".len + blk: { │ │72 - var len: usize = 0; │ │73 - for (std.enums.values(hash.HashKind)) |hash_kind| len = @max(len, hash.hexLen(hash_kind));│ │74 - break :blk len; │ │69 + pub const Merged = struct { │ │70 + revision: MergeRevision, │ │71 + before_oid: []const u8, // all zeroes if the target did not exist │ │72 + after_oid: []const u8, │ │73 }; │ │74 │ │75 pub fn kind(self: Status) StatusKind { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 76 return std.meta.activeTag(self); │ │ 79 - } │ │ 80 - │ │ 81 - pub fn encode(self: Status, buffer: []u8) ![]const u8 { │ │ 82 - return switch (self) { │ │ 83 - .open => "open", │ │ 84 - .closed => "closed", │ │ 85 - .merged => |oid| try std.fmt.bufPrint(buffer, "merged {s}", .{oid}), │ │ 86 - }; │ │ 87 - } │ │ 88 - │ │ 89 - pub fn decode(encoded: []const u8) !Status { │ │ 90 - if (std.mem.eql(u8, encoded, "open")) return .open; │ │ 91 - if (std.mem.eql(u8, encoded, "closed")) return .closed; │ │ 92 - const prefix = "merged "; │ │ 93 - if (std.mem.startsWith(u8, encoded, prefix) and encoded.len != prefix.len) { │ │ 94 - return .{ .merged = encoded[prefix.len..] }; │ │ 95 - } │ │ 96 - return error.InvalidEnumTag; │ │ 97 - } │ │ 98 - │ │ 99 - pub fn jsonStringify(self: Status, jw: anytype) !void { │ │100 - var buffer: [max_encoded_len]u8 = undefined; │ │101 - try jw.write(self.encode(&buffer) catch return error.WriteFailed); │ │102 - } │ │103 - │ │104 - pub fn jsonParse(allocator: std.mem.Allocator, source: anytype, options: std.json.ParseOptions) !Status { │ │105 - return decode(try std.json.innerParse([]const u8, allocator, source, options)); │ │106 - } │ │107 - │ │108 - pub fn jsonParseFromValue(_: std.mem.Allocator, source: std.json.Value, _: std.json.ParseOptions) !Status {│ │109 - return switch (source) { │ │110 - .string => |encoded| decode(encoded), │ │111 - else => error.UnexpectedToken, │ │112 - }; │ │ 77 } │ │ 78 }; │ │ 79 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │182 │ │183 switch (record.event.status) { │ │184 .open, .closed => {}, │ │221 - .merged => |merged_oid| { │ │222 - try evt.PatchRev.validateOid(hash_kind, merged_oid); │ │185 + .merged => |merged| { │ │186 + try evt.PatchRev.validateOid(hash_kind, merged.before_oid); │ │187 + try evt.PatchRev.validateOid(hash_kind, merged.after_oid); │ │188 const id = revision_id orelse return error.InvalidPatch; │ │189 const selected = record.event.revision orelse return error.InvalidPatch; │ │225 - if (!selected.includesOid(merged_oid)) return error.InvalidPatch; │ │190 const revision = (try evt.PatchRev.readById(DB, hash_kind, haxy_moment.readOnly(), arena, &id)) orelse return error.InvalidPatch;│ │191 if (!selected.matches(revision)) return error.InvalidPatch; │ │192 }, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯