notification.rs

  1use strum::{Display, EnumIter, EnumString, IntoEnumIterator};
  2
  3// An integer indicating a type of notification. The variants' numerical
  4// values are stored in the database, so they should never be removed
  5// or changed.
  6#[repr(i32)]
  7#[derive(Copy, Clone, Debug, EnumIter, EnumString, Display)]
  8pub enum NotificationKind {
  9    ContactRequest = 0,
 10    ContactRequestAccepted = 1,
 11    ChannelInvitation = 2,
 12    ChannelMessageMention = 3,
 13}
 14
 15#[derive(Debug, Clone, PartialEq, Eq)]
 16pub enum Notification {
 17    ContactRequest {
 18        requester_id: u64,
 19    },
 20    ContactRequestAccepted {
 21        contact_id: u64,
 22    },
 23    ChannelInvitation {
 24        inviter_id: u64,
 25        channel_id: u64,
 26    },
 27    ChannelMessageMention {
 28        sender_id: u64,
 29        channel_id: u64,
 30        message_id: u64,
 31    },
 32}
 33
 34impl Notification {
 35    /// Load this notification from its generic representation, which is
 36    /// used to represent it in the database, and in the wire protocol.
 37    ///
 38    /// The order in which a given notification type's fields are listed must
 39    /// match the order they're listed in the `to_parts` method, and it must
 40    /// not change, because they're stored in that order in the database.
 41    pub fn from_parts(kind: NotificationKind, entity_ids: [Option<u64>; 3]) -> Option<Self> {
 42        use NotificationKind::*;
 43        Some(match kind {
 44            ContactRequest => Self::ContactRequest {
 45                requester_id: entity_ids[0]?,
 46            },
 47
 48            ContactRequestAccepted => Self::ContactRequest {
 49                requester_id: entity_ids[0]?,
 50            },
 51
 52            ChannelInvitation => Self::ChannelInvitation {
 53                inviter_id: entity_ids[0]?,
 54                channel_id: entity_ids[1]?,
 55            },
 56
 57            ChannelMessageMention => Self::ChannelMessageMention {
 58                sender_id: entity_ids[0]?,
 59                channel_id: entity_ids[1]?,
 60                message_id: entity_ids[2]?,
 61            },
 62        })
 63    }
 64
 65    /// Convert this notification into its generic representation, which is
 66    /// used to represent it in the database, and in the wire protocol.
 67    ///
 68    /// The order in which a given notification type's fields are listed must
 69    /// match the order they're listed in the `from_parts` method, and it must
 70    /// not change, because they're stored in that order in the database.
 71    pub fn to_parts(&self) -> (NotificationKind, [Option<u64>; 3]) {
 72        use NotificationKind::*;
 73        match self {
 74            Self::ContactRequest { requester_id } => {
 75                (ContactRequest, [Some(*requester_id), None, None])
 76            }
 77
 78            Self::ContactRequestAccepted { contact_id } => {
 79                (ContactRequest, [Some(*contact_id), None, None])
 80            }
 81
 82            Self::ChannelInvitation {
 83                inviter_id,
 84                channel_id,
 85            } => (
 86                ChannelInvitation,
 87                [Some(*inviter_id), Some(*channel_id), None],
 88            ),
 89
 90            Self::ChannelMessageMention {
 91                sender_id,
 92                channel_id,
 93                message_id,
 94            } => (
 95                ChannelMessageMention,
 96                [Some(*sender_id), Some(*channel_id), Some(*message_id)],
 97            ),
 98        }
 99    }
100}
101
102impl NotificationKind {
103    pub fn all() -> impl Iterator<Item = Self> {
104        Self::iter()
105    }
106
107    pub fn from_i32(i: i32) -> Option<Self> {
108        Self::iter().find(|kind| *kind as i32 == i)
109    }
110}