misskey_api/model/
notification.rs

1use crate::model::{
2    id::Id,
3    note::{Note, Reaction},
4    user::User,
5    user_group::UserGroupInvitation,
6};
7
8use chrono::{DateTime, Utc};
9use serde::{Deserialize, Serialize};
10use strum_macros::EnumDiscriminants;
11use thiserror::Error;
12
13#[derive(Serialize, Deserialize, Debug, Clone)]
14#[serde(rename_all = "camelCase")]
15pub struct Notification {
16    pub id: Id<Notification>,
17    pub created_at: DateTime<Utc>,
18    /// This field is [`Id<User>`] (i.e. not [`Option`]) on <span class="module-item stab portability" style="display: inline-block; font-size: 80%;"><strong>non-<code style="background-color: transparent;">feature="12-17-0"</code></strong></span>.
19    #[cfg(feature = "12-27-0")]
20    pub user_id: Option<Id<User>>,
21    /// This field is [`User`] (i.e. not [`Option`]) on <span class="module-item stab portability" style="display: inline-block; font-size: 80%;"><strong>non-<code style="background-color: transparent;">feature="12-17-0"</code></strong></span>.
22    #[cfg(feature = "12-27-0")]
23    pub user: Option<User>,
24    #[cfg(not(feature = "12-27-0"))]
25    pub user_id: Id<User>,
26    #[cfg(not(feature = "12-27-0"))]
27    pub user: User,
28    #[cfg(feature = "12-39-0")]
29    #[cfg_attr(docsrs, doc(cfg(feature = "12-39-0")))]
30    pub is_read: bool,
31    #[serde(flatten)]
32    pub body: NotificationBody,
33}
34
35impl_entity!(Notification);
36
37#[derive(Serialize, Deserialize, Debug, Clone, EnumDiscriminants)]
38#[serde(rename_all = "camelCase", tag = "type")]
39#[strum_discriminants(name(NotificationType))]
40#[strum_discriminants(derive(Serialize, Deserialize, Hash))]
41#[strum_discriminants(serde(rename_all = "camelCase"))]
42pub enum NotificationBody {
43    Follow,
44    FollowRequestAccepted,
45    ReceiveFollowRequest,
46    Mention { note: Note },
47    Reply { note: Note },
48    Renote { note: Note },
49    Quote { note: Note },
50    Reaction { note: Note, reaction: Reaction },
51    PollVote { note: Note, choice: u64 },
52    GroupInvited { invitation: UserGroupInvitation },
53    // TODO: Implement
54    App {},
55}
56
57#[derive(Debug, Error, Clone)]
58#[error("invalid notification type")]
59pub struct ParseNotificationTypeError {
60    _priv: (),
61}
62
63impl std::str::FromStr for NotificationType {
64    type Err = ParseNotificationTypeError;
65
66    fn from_str(s: &str) -> Result<NotificationType, Self::Err> {
67        match s {
68            "follow" | "Follow" => Ok(NotificationType::Follow),
69            "followRequestAccepted" | "FollowRequestAccepted" => {
70                Ok(NotificationType::FollowRequestAccepted)
71            }
72            "receiveFollowRequest" | "ReceiveFollowRequest" => {
73                Ok(NotificationType::ReceiveFollowRequest)
74            }
75            "mention" | "Mention" => Ok(NotificationType::Mention),
76            "reply" | "Reply" => Ok(NotificationType::Reply),
77            "renote" | "Renote" => Ok(NotificationType::Renote),
78            "quote" | "Quote" => Ok(NotificationType::Quote),
79            "reaction" | "Reaction" => Ok(NotificationType::Reaction),
80            "pollVote" | "PollVote" => Ok(NotificationType::PollVote),
81            "groupInvited" | "GroupInvited" => Ok(NotificationType::GroupInvited),
82            "app" | "App" => Ok(NotificationType::App),
83            _ => Err(ParseNotificationTypeError { _priv: () }),
84        }
85    }
86}