╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───────────────╮ │src/event/Discussion.zig│ ╰────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │163 - if (!fieldsValid(title, tags)) return error.InvalidFields; │ │163 + if (!fieldsValid(title, labels)) return error.InvalidFields;│ │164 │ │165 var arena = std.heap.ArenaAllocator.init(allocator); │ │166 defer arena.deinit(); │ ╰─────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────╮ │173 .author = author, │ │174 .event = .{ .discuss = .{ │ │175 .title = title, │ │176 - .tags = tags, │ │176 + .labels = labels, │ │177 .description = description,│ │178 } }, │ │179 }}); │ ╰────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │180 } │ │181 │ │182 -fn removeFromTagSets(comptime DB: type, tags: DB.SortedMap(.read_write), names: []const u8, order_key: []const u8) !void { │ │183 - var tag_iter = tagIterator(names); │ │184 - while (tag_iter.next()) |tag| { │ │185 - if (tag.len == 0 or tag.len > tag_max_len) continue; │ │186 - const cursor = try tags.putCursor(tag); │ │182 +fn removeFromLabelSets(comptime DB: type, labels: DB.SortedMap(.read_write), names: []const u8, order_key: []const u8) !void {│ │183 + var label_iter = labelIterator(names); │ │184 + while (label_iter.next()) |label| { │ │185 + if (label.len == 0 or label.len > label_max_len) continue; │ │186 + const cursor = try labels.putCursor(label); │ │187 const set = try DB.SortedSet(.read_write).init(cursor); │ │188 _ = try set.remove(order_key); │ │189 - if (0 == try set.count()) _ = try tags.remove(tag); │ │189 + if (0 == try set.count()) _ = try labels.remove(label); │ │190 } │ │191 } │ │192 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │193 -fn addToTagSets(comptime DB: type, tags: DB.SortedMap(.read_write), names: []const u8, order_key: []const u8) !void { │ │194 - var tag_iter = tagIterator(names); │ │195 - while (tag_iter.next()) |tag| { │ │196 - if (tag.len == 0 or tag.len > tag_max_len) continue; │ │197 - const set = try DB.SortedSet(.read_write).init(try tags.putCursor(tag)); │ │193 +fn addToLabelSets(comptime DB: type, labels: DB.SortedMap(.read_write), names: []const u8, order_key: []const u8) !void {│ │194 + var label_iter = labelIterator(names); │ │195 + while (label_iter.next()) |label| { │ │196 + if (label.len == 0 or label.len > label_max_len) continue; │ │197 + const set = try DB.SortedSet(.read_write).init(try labels.putCursor(label)); │ │198 try set.put(order_key); │ │199 } │ │200 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────╮ │src/event/Issue.zig│ ╰───────────────────╯ ╭──────────────────────────────────────────────────────────────────────────╮ │ 8 │ │ 9 title: []const u8, │ │10 description: []const u8, │ │11 -tags: []const u8, // space-separated │ │11 +labels: []const u8, // space-separated │ │12 status: Status = .open, │ │13 │ │14 // what the db stores: the event's data plus the commit-derived fields│ ╰──────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────╮ │33 }; │ │34 }; │ │35 │ │36 -pub const tag_max_len = 64; │ │36 +pub const label_max_len = 64; │ │37 │ │38 // the moment keys `evt.merge` reads and writes for this kind│ │39 pub const merge_policy: evt.MergePolicy = .field_conflicts; │ ╰─────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────╮ │42 pub const conflicts_key = "conflicted-issue-id->conflict"; │ │43 pub const id_to_field_to_oid_key = "issue-id->field->oid"; │ │44 pub const status_to_id_set_key = "status->issue-id-set"; │ │45 -pub const tag_status_to_id_set_key = "tag+status->issue-id-set"; │ │45 +pub const label_status_to_id_set_key = "label+status->issue-id-set"; │ │46 │ │47 -// a "tag status" key names a tag's per-status issue set (tags can't contain │ │47 +// a "label status" key names a label's per-status issue set (labels can't contain │ │48 // spaces, so the pair is unambiguous) │ │49 -pub const TagStatusKey = [tag_max_len + 1 + Status.longest_len]u8; │ │49 +pub const LabelStatusKey = [label_max_len + 1 + Status.longest_len]u8; │ │50 │ │51 -pub fn tagStatusKey(buffer: *TagStatusKey, tag: []const u8, status: Status) ![]const u8 { │ │52 - return std.fmt.bufPrint(buffer, "{s} {s}", .{ tag, @tagName(status) }); │ │51 +pub fn labelStatusKey(buffer: *LabelStatusKey, label: []const u8, status: Status) ![]const u8 {│ │52 + return std.fmt.bufPrint(buffer, "{s} {s}", .{ label, @tagName(status) }); │ │53 } │ │54 │ │55 -pub fn tagIterator(tags: []const u8) std.mem.SplitIterator(u8, .scalar) { │ │56 - return std.mem.splitScalar(u8, tags, ' '); │ │55 +pub fn labelIterator(labels: []const u8) std.mem.SplitIterator(u8, .scalar) { │ │56 + return std.mem.splitScalar(u8, labels, ' '); │ │57 } │ │58 │ │59 -// a title is required, and a too-long tag would go unindexed once consumed │ │60 -pub fn fieldsValid(title: []const u8, tags: []const u8) bool { │ │59 +// a title is required, and a too-long label would go unindexed once consumed │ │60 +pub fn fieldsValid(title: []const u8, labels: []const u8) bool { │ │61 if (!evt.titleValid(title)) return false; │ │62 - var tag_iter = tagIterator(tags); │ │63 - while (tag_iter.next()) |tag| { │ │64 - if (tag.len > tag_max_len) return false; │ │62 + var label_iter = labelIterator(labels); │ │63 + while (label_iter.next()) |label| { │ │64 + if (label.len > label_max_len) return false; │ │65 } │ │66 return true; │ │67 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │87 const status_to_issues_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, status_to_id_set_key)); │ │88 const status_to_issues = try DB.SortedMap(.read_write).init(status_to_issues_cursor); │ │89 │ │90 - // the per-tag, per-status sets, keyed "tag,status" │ │91 - const tag_to_issues_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, tag_status_to_id_set_key)); │ │92 - const tag_to_issues = try DB.SortedMap(.read_write).init(tag_to_issues_cursor); │ │90 + // the per-label, per-status sets, keyed "label,status" │ │91 + const label_to_issues_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, label_status_to_id_set_key));│ │92 + const label_to_issues = try DB.SortedMap(.read_write).init(label_to_issues_cursor); │ │93 │ │94 const conflicts_cursor = try haxy_moment.putCursor(hash.hashInt(hash_kind, conflicts_key)); │ │95 const conflicts = try DB.SortedMap(.read_write).init(conflicts_cursor); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │111 record_to_write.created_order = existing_record.created_order; │ │112 record_to_write.author_email = existing_record.author_email; │ │113 │ │114 - // drop the old status's and tags' entries; active values are re-added below │ │114 + // drop the old status's and labels' entries; active values are re-added below │ │115 const order_key = evt.orderKeyDesc(existing_record.created_order, event_id); │ │116 if (!existing_record.removed) { │ │117 const status_set = try statusSet(DB, status_to_issues, existing_record.event.status);│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │118 _ = try status_set.remove(&order_key); │ │119 - try removeFromTagSets(DB, tag_to_issues, existing_record.event.tags, existing_record.event.status, &order_key); │ │119 + try removeFromLabelSets(DB, label_to_issues, existing_record.event.labels, existing_record.event.status, &order_key);│ │120 } │ │121 │ │122 // any event settles the conflict, since resolving in the ui may │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯