1use serde::{Deserialize, Deserializer, Serialize, de};
2
3use crate::ids::{Aid, Bvid, Mid};
4
5#[derive(Debug, Clone, Serialize, Deserialize)]
7pub struct UserCardProfile {
8 pub card: UserCardSummary,
10 pub following: bool,
12 #[serde(default)]
14 pub archive_count: u64,
15 #[serde(default)]
17 pub article_count: u64,
18 #[serde(default)]
20 pub follower: u64,
21 #[serde(default)]
23 pub like_num: u64,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
28pub struct UserCardSummary {
29 #[serde(deserialize_with = "deserialize_mid_from_string_or_number")]
31 pub mid: Mid,
32 pub name: String,
34 #[serde(default)]
36 pub sex: Option<String>,
37 pub face: String,
39 #[serde(default)]
41 pub sign: String,
42 #[serde(default)]
44 pub fans: u64,
45 #[serde(default)]
47 pub attention: u64,
48}
49
50#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52pub struct UserBatchCard {
53 pub mid: Mid,
55 pub name: String,
57 pub face: String,
59 #[serde(default)]
61 pub sign: String,
62 #[serde(default)]
64 pub rank: i32,
65 #[serde(default)]
67 pub level: i32,
68 #[serde(default)]
70 pub silence: i32,
71}
72
73#[derive(Debug, Clone, Serialize, Deserialize)]
75pub struct UserBatchInfo {
76 pub mid: Mid,
78 pub name: String,
80 #[serde(default)]
82 pub sign: String,
83 #[serde(default)]
85 pub rank: i32,
86 #[serde(default)]
88 pub level: i32,
89 #[serde(default)]
91 pub silence: i32,
92 #[serde(default, deserialize_with = "deserialize_optional_string")]
94 pub sex: Option<String>,
95 pub face: String,
97 #[serde(default)]
99 pub vip: Option<UserBatchVip>,
100 #[serde(default)]
102 pub official: Option<UserOfficialSummary>,
103 #[serde(default)]
105 pub is_fake_account: Option<u32>,
106 #[serde(default)]
108 pub expert_info: Option<serde_json::Value>,
109}
110
111#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
113pub struct UserBatchVip {
114 #[serde(default, rename = "type")]
116 pub kind: i32,
117 #[serde(default)]
119 pub status: i32,
120 #[serde(default)]
122 pub due_date: i64,
123 #[serde(default)]
125 pub vip_pay_type: i32,
126 #[serde(default)]
128 pub theme_type: i32,
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
133pub struct UserSpaceProfile {
134 pub mid: Mid,
136 pub name: String,
138 #[serde(default, deserialize_with = "deserialize_optional_string")]
140 pub sex: Option<String>,
141 pub face: String,
143 #[serde(default)]
145 pub sign: String,
146 pub level: u8,
148 pub silence: u8,
150 #[serde(default)]
152 pub coins: f64,
153 #[serde(default)]
155 pub fans_badge: bool,
156 #[serde(default)]
158 pub is_followed: bool,
159 #[serde(default, deserialize_with = "deserialize_optional_string")]
161 pub top_photo: Option<String>,
162 #[serde(default)]
164 pub official: Option<UserOfficialSummary>,
165 #[serde(default)]
167 pub vip: Option<UserVipSummary>,
168 #[serde(default)]
170 pub live_room: Option<UserSpaceLiveRoom>,
171}
172
173#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
175pub struct UserOfficialSummary {
176 #[serde(default)]
178 pub role: i32,
179 #[serde(default)]
181 pub title: String,
182 #[serde(default)]
184 pub desc: String,
185 #[serde(default, rename = "type")]
187 pub kind: i32,
188}
189
190#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
192pub struct UserVipSummary {
193 #[serde(default, rename = "type")]
195 pub kind: i32,
196 #[serde(default)]
198 pub status: i32,
199}
200
201#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
203pub struct UserSpaceLiveRoom {
204 #[serde(default, rename = "roomStatus")]
206 pub room_status: u8,
207 #[serde(default, rename = "liveStatus")]
209 pub live_status: u8,
210 #[serde(default)]
212 pub url: String,
213 #[serde(default)]
215 pub title: String,
216 #[serde(default, rename = "roomid")]
218 pub room_id: u64,
219}
220
221#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
223#[serde(transparent)]
224pub struct UserSpaceNotice {
225 pub content: String,
227}
228
229#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct UserBangumiFollowList {
232 #[serde(default, rename = "list")]
234 pub items: Vec<UserBangumiFollow>,
235 #[serde(default, rename = "pn")]
237 pub page: u32,
238 #[serde(default, rename = "ps")]
240 pub page_size: u32,
241 #[serde(default)]
243 pub total: u64,
244}
245
246#[derive(Debug, Clone, Serialize, Deserialize)]
248pub struct UserBangumiFollow {
249 pub season_id: i64,
251 pub media_id: i64,
253 #[serde(default)]
255 pub season_type: i64,
256 #[serde(default)]
258 pub season_type_name: String,
259 #[serde(default)]
261 pub title: String,
262 #[serde(default)]
264 pub cover: String,
265 #[serde(default)]
267 pub total_count: i64,
268 #[serde(default)]
270 pub is_finish: i64,
271 #[serde(default)]
273 pub is_started: i64,
274 #[serde(default)]
276 pub is_play: i64,
277 #[serde(default)]
279 pub badge: String,
280 #[serde(default)]
282 pub badge_type: i64,
283 #[serde(default, rename = "new_ep")]
285 pub latest_episode: UserBangumiLatestEpisode,
286 #[serde(default)]
288 pub rating: Option<UserBangumiRating>,
289 #[serde(default)]
291 pub url: String,
292 #[serde(default)]
294 pub short_url: String,
295 #[serde(default)]
297 pub summary: String,
298 #[serde(default)]
300 pub styles: Vec<String>,
301 #[serde(default)]
303 pub follow_status: i64,
304 #[serde(default)]
306 pub progress: String,
307 #[serde(default)]
309 pub both_follow: bool,
310}
311
312#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
314pub struct UserBangumiLatestEpisode {
315 #[serde(default)]
317 pub id: i64,
318 #[serde(default)]
320 pub index_show: String,
321 #[serde(default)]
323 pub cover: String,
324 #[serde(default)]
326 pub title: String,
327 #[serde(default)]
329 pub long_title: Option<String>,
330 #[serde(default)]
332 pub pub_time: String,
333 #[serde(default)]
335 pub duration: i64,
336}
337
338#[derive(Debug, Clone, Copy, PartialEq, Serialize, Deserialize)]
340pub struct UserBangumiRating {
341 #[serde(default)]
343 pub score: f64,
344 #[serde(default)]
346 pub count: i64,
347}
348
349#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
351pub struct UserRelationStat {
352 pub mid: Mid,
354 pub following: u64,
356 #[serde(default)]
358 pub whisper: u64,
359 #[serde(default)]
361 pub black: u64,
362 pub follower: u64,
364}
365
366#[derive(Debug, Clone, Serialize, Deserialize)]
368pub struct UserFollowings {
369 #[serde(default)]
371 pub list: Vec<UserFollowing>,
372 #[serde(default)]
374 pub re_version: u32,
375 #[serde(default)]
377 pub total: u64,
378}
379
380#[derive(Debug, Clone, Serialize, Deserialize)]
382pub struct UserFollowing {
383 pub mid: Mid,
385 #[serde(default)]
387 pub attribute: u8,
388 #[serde(default)]
390 pub mtime: u64,
391 #[serde(default)]
393 pub tag: Option<Vec<u64>>,
394 #[serde(default)]
396 pub special: u8,
397 #[serde(default, rename = "uname")]
399 pub name: String,
400 #[serde(default)]
402 pub face: String,
403 #[serde(default)]
405 pub sign: String,
406 #[serde(default)]
408 pub face_nft: u8,
409 #[serde(default)]
411 pub official_verify: Option<UserRelationOfficialVerify>,
412 #[serde(default)]
414 pub vip: Option<serde_json::Value>,
415}
416
417#[derive(Debug, Clone, Serialize, Deserialize)]
419pub struct UserFollowers {
420 #[serde(default)]
422 pub list: Vec<UserFollower>,
423 #[serde(default)]
425 pub offset: String,
426 #[serde(default)]
428 pub re_version: u32,
429 #[serde(default)]
431 pub total: u64,
432}
433
434#[derive(Debug, Clone, Serialize, Deserialize)]
436pub struct UserFollower {
437 pub mid: Mid,
439 #[serde(default)]
441 pub attribute: u8,
442 #[serde(default)]
444 pub mtime: Option<u64>,
445 #[serde(default)]
447 pub tag: Option<Vec<u64>>,
448 #[serde(default)]
450 pub special: u8,
451 #[serde(default)]
453 pub contract_info: Option<serde_json::Value>,
454 #[serde(default, rename = "uname")]
456 pub name: String,
457 #[serde(default)]
459 pub face: String,
460 #[serde(default)]
462 pub sign: String,
463 #[serde(default)]
465 pub face_nft: u8,
466 #[serde(default)]
468 pub official_verify: Option<UserRelationOfficialVerify>,
469 #[serde(default)]
471 pub vip: Option<serde_json::Value>,
472}
473
474#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
476pub struct UserFollowTag {
477 #[serde(rename = "tagid")]
479 pub id: i64,
480 pub name: String,
482 #[serde(default)]
484 pub count: i64,
485 #[serde(default)]
487 pub tip: Option<String>,
488}
489
490#[derive(Debug, Clone, Serialize, Deserialize)]
492pub struct UserMedalWall {
493 #[serde(default)]
495 pub list: Vec<UserMedalWallItem>,
496 #[serde(default)]
498 pub count: u32,
499 #[serde(default)]
501 pub close_space_medal: u32,
502 #[serde(default)]
504 pub only_show_wearing: u32,
505 #[serde(default)]
507 pub name: String,
508 #[serde(default)]
510 pub icon: String,
511 pub uid: Mid,
513 #[serde(default)]
515 pub level: u32,
516}
517
518#[derive(Debug, Clone, Serialize, Deserialize)]
520pub struct UserMedalWallItem {
521 pub medal_info: UserMedalInfo,
523 #[serde(default)]
525 pub target_name: String,
526 #[serde(default)]
528 pub target_icon: String,
529 #[serde(default)]
531 pub link: String,
532 #[serde(default)]
534 pub live_status: u32,
535 #[serde(default, rename = "offical")]
537 pub official: Option<u32>,
538 #[serde(default)]
540 pub uinfo_medal: Option<UserMedalOwnerInfo>,
541}
542
543impl UserMedalWallItem {
544 pub fn target_id(&self) -> Mid {
546 self.medal_info.target_id
547 }
548}
549
550#[derive(Debug, Clone, Serialize, Deserialize)]
552pub struct UserMedalInfo {
553 pub target_id: Mid,
555 #[serde(default)]
557 pub level: u32,
558 #[serde(default, rename = "medal_name")]
560 pub name: String,
561 #[serde(default)]
563 pub medal_color_start: u32,
564 #[serde(default)]
566 pub medal_color_end: u32,
567 #[serde(default)]
569 pub medal_color_border: u32,
570 #[serde(default)]
572 pub guard_level: u32,
573 #[serde(default)]
575 pub wearing_status: u32,
576 #[serde(default)]
578 pub medal_id: u64,
579 #[serde(default)]
581 pub intimacy: u64,
582 #[serde(default)]
584 pub next_intimacy: u64,
585 #[serde(default)]
587 pub today_feed: u64,
588 #[serde(default)]
590 pub day_limit: u64,
591 #[serde(default)]
593 pub guard_icon: Option<String>,
594 #[serde(default)]
596 pub honor_icon: Option<String>,
597}
598
599#[derive(Debug, Clone, Serialize, Deserialize)]
601pub struct UserMedalOwnerInfo {
602 #[serde(default)]
604 pub name: String,
605 #[serde(default)]
607 pub level: u32,
608 #[serde(default)]
610 pub color_start: u32,
611 #[serde(default)]
613 pub color_end: u32,
614 #[serde(default)]
616 pub color_border: u32,
617 #[serde(default)]
619 pub color: u32,
620 #[serde(default)]
622 pub id: u64,
623 #[serde(default)]
625 pub typ: u32,
626 #[serde(default)]
628 pub is_light: u32,
629 pub ruid: Mid,
631 #[serde(default)]
633 pub guard_level: u32,
634 #[serde(default)]
636 pub score: u64,
637 #[serde(default)]
639 pub guard_icon: Option<String>,
640 #[serde(default)]
642 pub honor_icon: Option<String>,
643 #[serde(default)]
645 pub v2_medal_color_start: Option<String>,
646 #[serde(default)]
648 pub v2_medal_color_end: Option<String>,
649 #[serde(default)]
651 pub v2_medal_color_border: Option<String>,
652 #[serde(default)]
654 pub v2_medal_color_text: Option<String>,
655 #[serde(default)]
657 pub v2_medal_color_level: Option<String>,
658 #[serde(default)]
660 pub user_receive_count: Option<u32>,
661}
662
663#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
665pub struct UserRelationOfficialVerify {
666 #[serde(default, rename = "type")]
668 pub kind: i8,
669 #[serde(default)]
671 pub desc: String,
672}
673
674#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
676pub struct UserUpStat {
677 pub archive: UserUpStatArchive,
679 pub article: UserUpStatArticle,
681 pub likes: u64,
683}
684
685#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
687pub struct UserUpStatArchive {
688 #[serde(default)]
690 pub view: u64,
691}
692
693#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
695pub struct UserUpStatArticle {
696 #[serde(default)]
698 pub view: u64,
699}
700
701#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
703pub struct UserNavStat {
704 #[serde(default)]
706 pub video: u64,
707 #[serde(default)]
709 pub bangumi: u64,
710 #[serde(default)]
712 pub cinema: u64,
713 #[serde(default)]
715 pub channel: UserNavStatPair,
716 #[serde(default)]
718 pub favourite: UserNavStatPair,
719 #[serde(default)]
721 pub tag: u64,
722 #[serde(default)]
724 pub article: u64,
725 #[serde(default)]
727 pub playlist: u64,
728 #[serde(default)]
730 pub album: u64,
731 #[serde(default)]
733 pub audio: u64,
734 #[serde(default)]
736 pub pugv: u64,
737 #[serde(default)]
739 pub opus: u64,
740 #[serde(default, rename = "season_num")]
742 pub season_count: u64,
743}
744
745#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize)]
747pub struct UserNavStatPair {
748 #[serde(default)]
750 pub master: u64,
751 #[serde(default)]
753 pub guest: u64,
754}
755
756#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
758pub struct UserAlbumCount {
759 #[serde(default)]
761 pub all_count: u64,
762 #[serde(default)]
764 pub draw_count: u64,
765 #[serde(default)]
767 pub photo_count: u64,
768 #[serde(default)]
770 pub daily_count: u64,
771}
772
773#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
775pub struct UserNameToUid {
776 #[serde(default)]
778 pub uid_list: Vec<UserNameToUidItem>,
779}
780
781#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
783pub struct UserNameToUidItem {
784 pub name: String,
786 #[serde(
788 rename = "uid",
789 deserialize_with = "deserialize_mid_from_string_or_number"
790 )]
791 pub mid: Mid,
792}
793
794#[derive(Debug, Clone, Serialize, Deserialize)]
796pub struct UserUploadedVideos {
797 pub list: UserUploadedVideoList,
799 pub page: UserUploadedVideosPage,
801 #[serde(default)]
803 pub episodic_button: Option<UserUploadedVideosButton>,
804 #[serde(default)]
806 pub is_risk: bool,
807}
808
809#[derive(Debug, Clone, Serialize, Deserialize)]
811pub struct UserUploadedVideoList {
812 #[serde(default)]
814 pub tlist: serde_json::Value,
815 #[serde(default, rename = "vlist")]
817 pub videos: Vec<UserUploadedVideo>,
818}
819
820#[derive(Debug, Clone, Serialize, Deserialize)]
822pub struct UserUploadedVideo {
823 pub aid: Aid,
825 pub bvid: Bvid,
827 pub mid: Mid,
829 pub title: String,
831 #[serde(default)]
833 pub author: String,
834 #[serde(default)]
836 pub pic: String,
837 #[serde(default)]
839 pub length: String,
840 #[serde(default)]
842 pub description: String,
843 #[serde(default)]
845 pub created: u64,
846 #[serde(default)]
848 pub play: u64,
849 #[serde(default)]
851 pub comment: u64,
852 #[serde(default)]
854 pub typeid: u64,
855 #[serde(default)]
857 pub video_review: u64,
858 #[serde(default)]
860 pub hide_click: bool,
861}
862
863#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
865pub struct UserUploadedVideosPage {
866 #[serde(default)]
868 pub count: u64,
869 #[serde(default)]
871 pub pn: u32,
872 #[serde(default)]
874 pub ps: u32,
875}
876
877#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
879pub struct UserUploadedVideosButton {
880 #[serde(default)]
882 pub text: String,
883 #[serde(default)]
885 pub uri: String,
886}
887
888fn deserialize_mid_from_string_or_number<'de, D>(deserializer: D) -> Result<Mid, D::Error>
889where
890 D: Deserializer<'de>,
891{
892 let value = serde_json::Value::deserialize(deserializer)?;
893
894 match value {
895 serde_json::Value::Number(number) => {
896 let mid = number
897 .as_u64()
898 .ok_or_else(|| de::Error::custom("mid must be a non-negative integer"))?;
899 Mid::new(mid).map_err(de::Error::custom)
900 }
901 serde_json::Value::String(text) => text.parse::<Mid>().map_err(de::Error::custom),
902 _ => Err(de::Error::custom("mid must be a string or number")),
903 }
904}
905
906fn deserialize_optional_string<'de, D>(deserializer: D) -> Result<Option<String>, D::Error>
907where
908 D: Deserializer<'de>,
909{
910 Ok(Option::<String>::deserialize(deserializer)?
911 .and_then(|value| (!value.trim().is_empty()).then_some(value)))
912}