use serde::Deserialize;
use serde_json::Value;
use crate::model::article::ArticleTag;
use crate::model::bool_from_int;
use crate::{impl_str_enum, utils::error::Error};
#[derive(Debug, Clone)]
#[repr(u8)]
pub enum Notice {
Article = 0,
Comment = 1,
At = 2,
Commented = 3,
FollowingUser = 4,
PointCharge = 5,
PointTransfer = 6,
PointArticleReward = 7,
PointCommentThank = 8,
Broadcast = 9,
PointExchange = 10,
AbusePointDeduct = 11,
PointArticleThank = 12,
Reply = 13,
InvitecodeUsed = 14,
SysAnnounceArticle = 15,
SysAnnounceNewUser = 16,
NewFollower = 17,
InvitationLinkUsed = 18,
SysAnnounceRoleChanged = 19,
FollowingArticleUpdate = 20,
FollowingArticleComment = 21,
PointPerfectArticle = 22,
ArticleNewFollower = 23,
ArticleNewWatcher = 24,
CommentVoteUp = 25,
CommentVoteDown = 26,
ArticleVoteUp = 27,
ArticleVoteDown = 28,
PointCommentAccept = 33,
PointReportHandled = 36,
ChatRoomAt = 38,
RedPacket = 39,
}
#[derive(Debug, Clone)]
pub enum NoticeType {
Point,
Commented,
Reply,
At,
Following,
Broadcast,
System,
}
impl_str_enum!(NoticeType {
Point => "point",
Commented => "commented",
Reply => "reply",
At => "at",
Following => "following",
Broadcast => "broadcast",
System => "sys-announce",
});
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticeCount {
#[serde(rename = "userNotifyStatus", deserialize_with = "bool_from_int")]
pub notifyStatus: bool,
#[serde(rename = "unreadNotificationCnt")]
pub count: u64,
#[serde(rename = "unreadReplyNotificationCnt")]
pub reply: u64,
#[serde(rename = "unreadPointNotificationCnt")]
pub point: u64,
#[serde(rename = "unreadAtNotificationCnt")]
pub at: u64,
#[serde(rename = "unreadBroadcastNotificationCnt")]
pub broadcast: u64,
#[serde(rename = "unreadSysAnnounceNotificationCnt")]
pub sysAnnounce: u64,
#[serde(rename = "unreadNewFollowerNotificationCnt")]
pub newFollower: u64,
#[serde(rename = "unreadFollowingNotificationCnt")]
pub following: u64,
#[serde(rename = "unreadCommentedNotificationCnt")]
pub commented: u64,
}
impl NoticeCount {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticeCount: {}", e)))
}
}
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticePoint {
pub oId: String,
pub dataId: String,
pub userId: String,
pub dataType: u32,
pub description: String,
pub hasRead: bool,
pub createTime: String,
}
impl NoticePoint {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticePoint: {}", e)))
}
}
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticeComment {
pub oId: String,
#[serde(rename = "commentArticleTitle")]
pub title: String,
#[serde(rename = "commentAuthorName")]
pub author: String,
#[serde(rename = "commentAuthorThumbnailURL")]
pub thumbnailURL: String,
#[serde(rename = "commentArticleType")]
pub type_: u32,
#[serde(rename = "commentArticlePerfect", deserialize_with = "bool_from_int")]
pub perfect: bool,
#[serde(rename = "commentContent")]
pub content: String,
#[serde(rename = "commentSharpURL")]
pub sharpURL: String,
pub hasRead: bool,
pub createTime: String,
}
impl NoticeComment {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticeComment: {}", e)))
}
}
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticeAt {
pub oId: String,
pub dataType: u32,
pub userName: String,
#[serde(rename = "userAvatarURL")]
pub avatarURL: String,
pub content: String,
pub hasRead: bool,
pub createTime: String,
}
impl NoticeAt {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticeAt: {}", e)))
}
}
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticeFollow {
pub oId: String,
pub url: String,
pub dataType: u32,
#[serde(rename = "articleTitle")]
pub title: String,
#[serde(rename = "authorName")]
pub author: String,
pub content: String,
pub isComment: bool,
pub thumbnailURL: String,
#[serde(rename = "articleCommentCount")]
pub commentCnt: u32,
#[serde(rename = "articlePerfect", deserialize_with = "bool_from_int")]
pub perfect: bool,
#[serde(rename = "articleTagObjs")]
pub tagObjs: Vec<ArticleTag>,
#[serde(rename = "articleTags")]
pub tags: String,
#[serde(rename = "articleType")]
pub type_: u32,
pub hasRead: bool,
pub createTime: String,
}
impl NoticeFollow {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticeFollow: {}", e)))
}
}
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticeSystem {
pub oId: String,
pub userId: String,
pub dataId: String,
pub dataType: u32,
pub description: String,
pub hasRead: bool,
pub createTime: String,
}
impl NoticeSystem {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticeSystem: {}", e)))
}
}
#[derive(Debug, Clone)]
pub enum NoticeMsgType {
Refresh,
WarnBroadcast,
}
impl NoticeMsgType {
pub fn values() -> Vec<&'static str> {
vec!["refreshNotification", "warnBroadcast"]
}
}
impl_str_enum!(NoticeMsgType {
Refresh => "refreshNotification",
WarnBroadcast => "warnBroadcast",
});
#[derive(Clone, Debug, Deserialize)]
#[allow(non_snake_case)]
pub struct NoticeMsg {
pub command: String,
pub userId: String,
#[serde(rename = "warnBroadcastText")]
pub content: Option<String>,
pub who: Option<String>,
}
impl NoticeMsg {
pub fn from_value(data: &Value) -> Result<Self, Error> {
serde_json::from_value(data.clone())
.map_err(|e| Error::Parse(format!("Failed to parse NoticeMsg: {}", e)))
}
}
#[derive(Clone, Debug)]
pub enum NoticeItem {
Point(NoticePoint),
Comment(NoticeComment),
At(NoticeAt),
Follow(NoticeFollow),
System(NoticeSystem),
}
pub type NoticeList = Vec<NoticeItem>;
impl NoticeItem {
pub fn from_value(data: &Value, notice_type: &NoticeType) -> Result<Self, Error> {
match notice_type {
NoticeType::Point => Ok(NoticeItem::Point(NoticePoint::from_value(data)?)),
NoticeType::Commented => Ok(NoticeItem::Comment(NoticeComment::from_value(data)?)),
NoticeType::At => Ok(NoticeItem::At(NoticeAt::from_value(data)?)),
NoticeType::Following => Ok(NoticeItem::Follow(NoticeFollow::from_value(data)?)),
NoticeType::System => Ok(NoticeItem::System(NoticeSystem::from_value(data)?)),
_ => Err(Error::Parse("Unsupported notice type".to_string())),
}
}
}