╭ changed ─────────╮ │src/event/Repo.zig│ ╰──────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │32 public, │ │33 }; │ │34 │ │35 +// what a user may do in a repo, ordered so a higher role includes the lower ones │ │36 +pub const Role = enum { │ │37 + none, │ │38 + read, │ │39 + write, │ │40 + owner, │ │41 + │ │42 + pub fn atLeast(self: Role, min: Role) bool { │ │43 + return @intFromEnum(self) >= @intFromEnum(min); │ │44 + } │ │45 +}; │ │46 + │ │47 pub const name_max_len = 32; │ │48 + │ │49 +// the role `user_id_maybe` holds in the repo. null is a logged-out user, who │ │50 +// gets the base role the access fields give everyone. │ │51 +pub fn roleOf(record: Record, user_id_maybe: ?[evt.event_id_size]u8) Role { │ │52 + const event = record.event; │ │53 + const base: Role = if (event.write_access == .public) .write else if (event.read_access == .public) .read else .none;│ │54 + const user_id = user_id_maybe orelse return base; │ │55 + if (std.mem.eql(u8, event.user_id, &user_id)) return .owner; │ │56 │ │57 + const user_id_hex = std.fmt.bytesToHex(user_id, .lower); │ │58 + if (base == .write or containsUserId(event.write_user_ids, &user_id_hex)) return .write; │ │59 + if (base == .read or containsUserId(event.read_user_ids, &user_id_hex)) return .read; │ │60 + return .none; │ │61 +} │ │62 + │ │63 +fn containsUserId(user_ids: []const u8, user_id_hex: []const u8) bool { │ │64 + var lines = std.mem.tokenizeScalar(u8, user_ids, '\n'); │ │65 + while (lines.next()) |id| { │ │66 + if (std.mem.eql(u8, id, user_id_hex)) return true; │ │67 + } │ │68 + return false; │ │69 +} │ │70 + │ │71 // the moment keys `evt.merge` reads and writes for this kind │ │72 pub const merge_policy: evt.MergePolicy = .target_wins; │ │73 pub const record_map_key = "event-id->repo"; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯