forge
ExploreLog in

Tahinli/forge

public
0 watching
★ 0
4.0 KiB
1//! Notification models: repo watch levels, issue subscriptions and inbox entries.
2
3use crate::model::Id;
4
5/// How much activity a user hears about in a repo. A user with no row is `Participating`.
6#[derive(Debug, Clone, Copy, PartialEq, Eq)]
7pub enum WatchLevel {
8 /// All activity in the repo.
9 Watching,
10 /// Only the issues and pulls the user is subscribed to, and mentions.
11 Participating,
12 /// Nothing from the repo, even subscribed threads. Mentions still notify.
13 Ignoring,
14}
15
16impl WatchLevel {
17 pub fn as_str(self) -> &'static str {
18 match self {
19 WatchLevel::Watching => "watching",
20 WatchLevel::Participating => "participating",
21 WatchLevel::Ignoring => "ignoring",
22 }
23 }
24
25 pub fn parse(s: &str) -> Option<WatchLevel> {
26 match s {
27 "watching" => Some(WatchLevel::Watching),
28 "participating" => Some(WatchLevel::Participating),
29 "ignoring" => Some(WatchLevel::Ignoring),
30 _ => None,
31 }
32 }
33}
34
35/// State of an issue subscription row.
36#[derive(Debug, Clone, Copy, PartialEq, Eq)]
37pub enum SubState {
38 Subscribed,
39 /// Explicit opt-out. Auto-subscribe never replaces it.
40 Ignored,
41}
42
43impl SubState {
44 pub fn as_str(self) -> &'static str {
45 match self {
46 SubState::Subscribed => "subscribed",
47 SubState::Ignored => "ignored",
48 }
49 }
50
51 pub fn parse(s: &str) -> Option<SubState> {
52 match s {
53 "subscribed" => Some(SubState::Subscribed),
54 "ignored" => Some(SubState::Ignored),
55 _ => None,
56 }
57 }
58}
59
60/// Why a user is notified. The stronger reason wins while a thread is unread.
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum Reason {
63 Mention,
64 Assign,
65 ReviewRequested,
66 Author,
67 Comment,
68 StateChange,
69 Subscribed,
70 Watching,
71}
72
73impl Reason {
74 pub fn as_str(self) -> &'static str {
75 match self {
76 Reason::Mention => "mention",
77 Reason::Assign => "assign",
78 Reason::ReviewRequested => "review_requested",
79 Reason::Author => "author",
80 Reason::Comment => "comment",
81 Reason::StateChange => "state_change",
82 Reason::Subscribed => "subscribed",
83 Reason::Watching => "watching",
84 }
85 }
86
87 pub fn parse(s: &str) -> Option<Reason> {
88 match s {
89 "mention" => Some(Reason::Mention),
90 "assign" => Some(Reason::Assign),
91 "review_requested" => Some(Reason::ReviewRequested),
92 "author" => Some(Reason::Author),
93 "comment" => Some(Reason::Comment),
94 "state_change" => Some(Reason::StateChange),
95 "subscribed" => Some(Reason::Subscribed),
96 "watching" => Some(Reason::Watching),
97 _ => None,
98 }
99 }
100
101 /// Strength, higher is stronger: mention > assign > review_requested > author > comment >
102 /// state_change > subscribed > watching.
103 pub fn rank(self) -> u8 {
104 match self {
105 Reason::Mention => 8,
106 Reason::Assign => 7,
107 Reason::ReviewRequested => 6,
108 Reason::Author => 5,
109 Reason::Comment => 4,
110 Reason::StateChange => 3,
111 Reason::Subscribed => 2,
112 Reason::Watching => 1,
113 }
114 }
115}
116
117/// One inbox row joined with its repo, issue or pull, and the last actor.
118#[derive(Debug, Clone, PartialEq, Eq)]
119pub struct Notification {
120 pub id: Id,
121 pub repo_id: Id,
122 pub repo_owner: String,
123 pub repo_name: String,
124 pub issue_id: Id,
125 pub number: i64,
126 /// True for pull requests (`issues.kind = 'pull'`).
127 pub is_pull: bool,
128 pub title: String,
129 /// `open` or `closed`.
130 pub issue_state: String,
131 pub reason: Reason,
132 pub last_activity: String,
133 /// `None` when the actor was deleted without a ghost reassignment or the activity had none.
134 pub last_actor_name: Option<String>,
135 pub unread: bool,
136 pub updated_at: String,
137}