1use serde::Deserialize;
2use serde_json::Value;
3
4use crate::model::article::ArticleTag;
5use crate::model::bool_from_int;
6use crate::{impl_str_enum, utils::error::Error};
7
8#[derive(Debug, Clone)]
10#[repr(u8)]
11pub enum Notice {
12 Article = 0,
14 Comment = 1,
16 At = 2,
18 Commented = 3,
20 FollowingUser = 4,
22 PointCharge = 5,
24 PointTransfer = 6,
26 PointArticleReward = 7,
28 PointCommentThank = 8,
30 Broadcast = 9,
32 PointExchange = 10,
34 AbusePointDeduct = 11,
36 PointArticleThank = 12,
38 Reply = 13,
40 InvitecodeUsed = 14,
42 SysAnnounceArticle = 15,
44 SysAnnounceNewUser = 16,
46 NewFollower = 17,
48 InvitationLinkUsed = 18,
50 SysAnnounceRoleChanged = 19,
52 FollowingArticleUpdate = 20,
54 FollowingArticleComment = 21,
56 PointPerfectArticle = 22,
58 ArticleNewFollower = 23,
60 ArticleNewWatcher = 24,
62 CommentVoteUp = 25,
64 CommentVoteDown = 26,
66 ArticleVoteUp = 27,
68 ArticleVoteDown = 28,
70 PointCommentAccept = 33,
72 PointReportHandled = 36,
74 ChatRoomAt = 38,
76 RedPacket = 39,
78}
79
80#[derive(Debug, Clone)]
82pub enum NoticeType {
83 Point,
84 Commented,
85 Reply,
86 At,
87 Following,
88 Broadcast,
89 System,
90}
91
92impl_str_enum!(NoticeType {
93 Point => "point",
94 Commented => "commented",
95 Reply => "reply",
96 At => "at",
97 Following => "following",
98 Broadcast => "broadcast",
99 System => "sys-announce",
100});
101
102#[derive(Clone, Debug, Deserialize)]
103#[allow(non_snake_case)]
104pub struct NoticeCount {
105 #[serde(rename = "userNotifyStatus", deserialize_with = "bool_from_int")]
107 pub notifyStatus: bool,
108 #[serde(rename = "unreadNotificationCnt")]
110 pub count: u64,
111 #[serde(rename = "unreadReplyNotificationCnt")]
113 pub reply: u64,
114 #[serde(rename = "unreadPointNotificationCnt")]
116 pub point: u64,
117 #[serde(rename = "unreadAtNotificationCnt")]
119 pub at: u64,
120 #[serde(rename = "unreadBroadcastNotificationCnt")]
122 pub broadcast: u64,
123 #[serde(rename = "unreadSysAnnounceNotificationCnt")]
125 pub sysAnnounce: u64,
126 #[serde(rename = "unreadNewFollowerNotificationCnt")]
128 pub newFollower: u64,
129 #[serde(rename = "unreadFollowingNotificationCnt")]
131 pub following: u64,
132 #[serde(rename = "unreadCommentedNotificationCnt")]
134 pub commented: u64,
135}
136
137impl NoticeCount {
138 pub fn from_value(data: &Value) -> Result<Self, Error> {
139 serde_json::from_value(data.clone())
140 .map_err(|e| Error::Parse(format!("Failed to parse NoticeCount: {}", e)))
141 }
142}
143
144#[derive(Clone, Debug, Deserialize)]
146#[allow(non_snake_case)]
147pub struct NoticePoint {
148 pub oId: String,
150 pub dataId: String,
152 pub userId: String,
154 pub dataType: u32,
156 pub description: String,
158 pub hasRead: bool,
160 pub createTime: String,
162}
163
164impl NoticePoint {
165 pub fn from_value(data: &Value) -> Result<Self, Error> {
166 serde_json::from_value(data.clone())
167 .map_err(|e| Error::Parse(format!("Failed to parse NoticePoint: {}", e)))
168 }
169}
170
171#[derive(Clone, Debug, Deserialize)]
173#[allow(non_snake_case)]
174pub struct NoticeComment {
175 pub oId: String,
177 #[serde(rename = "commentArticleTitle")]
179 pub title: String,
180 #[serde(rename = "commentAuthorName")]
182 pub author: String,
183 #[serde(rename = "commentAuthorThumbnailURL")]
185 pub thumbnailURL: String,
186 #[serde(rename = "commentArticleType")]
188 pub type_: u32,
189 #[serde(rename = "commentArticlePerfect", deserialize_with = "bool_from_int")]
191 pub perfect: bool,
192 #[serde(rename = "commentContent")]
194 pub content: String,
195 #[serde(rename = "commentSharpURL")]
197 pub sharpURL: String,
198 pub hasRead: bool,
200 pub createTime: String,
202}
203
204impl NoticeComment {
205 pub fn from_value(data: &Value) -> Result<Self, Error> {
206 serde_json::from_value(data.clone())
207 .map_err(|e| Error::Parse(format!("Failed to parse NoticeComment: {}", e)))
208 }
209}
210
211#[derive(Clone, Debug, Deserialize)]
213#[allow(non_snake_case)]
214pub struct NoticeAt {
215 pub oId: String,
217 pub dataType: u32,
219 pub userName: String,
221 #[serde(rename = "userAvatarURL")]
223 pub avatarURL: String,
224 pub content: String,
226 pub hasRead: bool,
228 pub createTime: String,
230}
231
232impl NoticeAt {
233 pub fn from_value(data: &Value) -> Result<Self, Error> {
234 serde_json::from_value(data.clone())
235 .map_err(|e| Error::Parse(format!("Failed to parse NoticeAt: {}", e)))
236 }
237}
238
239#[derive(Clone, Debug, Deserialize)]
241#[allow(non_snake_case)]
242pub struct NoticeFollow {
243 pub oId: String,
245 pub url: String,
247 pub dataType: u32,
249 #[serde(rename = "articleTitle")]
251 pub title: String,
252 #[serde(rename = "authorName")]
254 pub author: String,
255 pub content: String,
257 pub isComment: bool,
259 pub thumbnailURL: String,
261 #[serde(rename = "articleCommentCount")]
263 pub commentCnt: u32,
264 #[serde(rename = "articlePerfect", deserialize_with = "bool_from_int")]
266 pub perfect: bool,
267 #[serde(rename = "articleTagObjs")]
269 pub tagObjs: Vec<ArticleTag>,
270 #[serde(rename = "articleTags")]
272 pub tags: String,
273 #[serde(rename = "articleType")]
275 pub type_: u32,
276 pub hasRead: bool,
278 pub createTime: String,
280}
281
282impl NoticeFollow {
283 pub fn from_value(data: &Value) -> Result<Self, Error> {
284 serde_json::from_value(data.clone())
285 .map_err(|e| Error::Parse(format!("Failed to parse NoticeFollow: {}", e)))
286 }
287}
288
289#[derive(Clone, Debug, Deserialize)]
291#[allow(non_snake_case)]
292pub struct NoticeSystem {
293 pub oId: String,
295 pub userId: String,
297 pub dataId: String,
299 pub dataType: u32,
301 pub description: String,
303 pub hasRead: bool,
305 pub createTime: String,
307}
308
309impl NoticeSystem {
310 pub fn from_value(data: &Value) -> Result<Self, Error> {
311 serde_json::from_value(data.clone())
312 .map_err(|e| Error::Parse(format!("Failed to parse NoticeSystem: {}", e)))
313 }
314}
315
316#[derive(Debug, Clone)]
318pub enum NoticeMsgType {
319 Refresh,
321 WarnBroadcast,
323}
324
325impl NoticeMsgType {
326 pub fn values() -> Vec<&'static str> {
327 vec!["refreshNotification", "warnBroadcast"]
328 }
329}
330
331impl_str_enum!(NoticeMsgType {
332 Refresh => "refreshNotification",
333 WarnBroadcast => "warnBroadcast",
334});
335
336#[derive(Clone, Debug, Deserialize)]
338#[allow(non_snake_case)]
339pub struct NoticeMsg {
340 pub command: String,
342 pub userId: String,
344 #[serde(rename = "warnBroadcastText")]
346 pub content: Option<String>,
347 pub who: Option<String>,
349}
350
351impl NoticeMsg {
352 pub fn from_value(data: &Value) -> Result<Self, Error> {
353 serde_json::from_value(data.clone())
354 .map_err(|e| Error::Parse(format!("Failed to parse NoticeMsg: {}", e)))
355 }
356}
357
358#[derive(Clone, Debug)]
360pub enum NoticeItem {
361 Point(NoticePoint),
363 Comment(NoticeComment),
365 At(NoticeAt),
367 Follow(NoticeFollow),
369 System(NoticeSystem),
371}
372
373pub type NoticeList = Vec<NoticeItem>;
374
375impl NoticeItem {
376 pub fn from_value(data: &Value, notice_type: &NoticeType) -> Result<Self, Error> {
377 match notice_type {
378 NoticeType::Point => Ok(NoticeItem::Point(NoticePoint::from_value(data)?)),
379 NoticeType::Commented => Ok(NoticeItem::Comment(NoticeComment::from_value(data)?)),
380 NoticeType::At => Ok(NoticeItem::At(NoticeAt::from_value(data)?)),
381 NoticeType::Following => Ok(NoticeItem::Follow(NoticeFollow::from_value(data)?)),
382 NoticeType::System => Ok(NoticeItem::System(NoticeSystem::from_value(data)?)),
383 _ => Err(Error::Parse("Unsupported notice type".to_string())),
384 }
385 }
386}