//! Notification models: repo watch levels, issue subscriptions and inbox entries. use crate::model::Id; /// How much activity a user hears about in a repo. A user with no row is `Participating`. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum WatchLevel { /// All activity in the repo. Watching, /// Only the issues and pulls the user is subscribed to, and mentions. Participating, /// Nothing from the repo, even subscribed threads. Mentions still notify. Ignoring, } impl WatchLevel { pub fn as_str(self) -> &'static str { match self { WatchLevel::Watching => "watching", WatchLevel::Participating => "participating", WatchLevel::Ignoring => "ignoring", } } pub fn parse(s: &str) -> Option { match s { "watching" => Some(WatchLevel::Watching), "participating" => Some(WatchLevel::Participating), "ignoring" => Some(WatchLevel::Ignoring), _ => None, } } } /// State of an issue subscription row. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum SubState { Subscribed, /// Explicit opt-out. Auto-subscribe never replaces it. Ignored, } impl SubState { pub fn as_str(self) -> &'static str { match self { SubState::Subscribed => "subscribed", SubState::Ignored => "ignored", } } pub fn parse(s: &str) -> Option { match s { "subscribed" => Some(SubState::Subscribed), "ignored" => Some(SubState::Ignored), _ => None, } } } /// Why a user is notified. The stronger reason wins while a thread is unread. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum Reason { Mention, Assign, ReviewRequested, Author, Comment, StateChange, Subscribed, Watching, } impl Reason { pub fn as_str(self) -> &'static str { match self { Reason::Mention => "mention", Reason::Assign => "assign", Reason::ReviewRequested => "review_requested", Reason::Author => "author", Reason::Comment => "comment", Reason::StateChange => "state_change", Reason::Subscribed => "subscribed", Reason::Watching => "watching", } } pub fn parse(s: &str) -> Option { match s { "mention" => Some(Reason::Mention), "assign" => Some(Reason::Assign), "review_requested" => Some(Reason::ReviewRequested), "author" => Some(Reason::Author), "comment" => Some(Reason::Comment), "state_change" => Some(Reason::StateChange), "subscribed" => Some(Reason::Subscribed), "watching" => Some(Reason::Watching), _ => None, } } /// Strength, higher is stronger: mention > assign > review_requested > author > comment > /// state_change > subscribed > watching. pub fn rank(self) -> u8 { match self { Reason::Mention => 8, Reason::Assign => 7, Reason::ReviewRequested => 6, Reason::Author => 5, Reason::Comment => 4, Reason::StateChange => 3, Reason::Subscribed => 2, Reason::Watching => 1, } } } /// One inbox row joined with its repo, issue or pull, and the last actor. #[derive(Debug, Clone, PartialEq, Eq)] pub struct Notification { pub id: Id, pub repo_id: Id, pub repo_owner: String, pub repo_name: String, pub issue_id: Id, pub number: i64, /// True for pull requests (`issues.kind = 'pull'`). pub is_pull: bool, pub title: String, /// `open` or `closed`. pub issue_state: String, pub reason: Reason, pub last_activity: String, /// `None` when the actor was deleted without a ghost reassignment or the activity had none. pub last_actor_name: Option, pub unread: bool, pub updated_at: String, }