1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
use serde::{Deserialize, Serialize};

#[derive(Serialize, Deserialize, Debug, Clone, Default)]
pub struct User {
    #[serde(skip_serializing_if = "Option::is_none")]
    pub open_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub union_id: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_url_100: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub avatar_large_url: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub display_name: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub bio_description: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub profile_deep_link: Option<String>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub is_verified: Option<bool>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub follower_count: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub following_count: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub likes_count: Option<i64>,
    #[serde(skip_serializing_if = "Option::is_none")]
    pub video_count: Option<i64>,
    #[serde(flatten)]
    pub extra: std::collections::HashMap<String, serde_json::Value>,
}

impl User {
    pub fn is_empty_extra(&self) -> bool {
        let res = self.extra.is_empty();
        if !res {
            println!("User {:?}", self.extra);
        }
        res
    }
}

#[derive(Debug, Clone)]
pub enum UserField {
    OpenId,
    UnionId,
    AvatarUrl,
    AvatarUrl100,
    AvatarLargeUrl,
    DisplayName,
    BioDescription,
    ProfileDeepLink,
    IsVerified,
    FollowerCount,
    FollowingCount,
    LikesCount,
    VideoCount,
}
impl std::fmt::Display for UserField {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::OpenId => write!(f, "open_id"),
            Self::UnionId => write!(f, "union_id"),
            Self::AvatarUrl => write!(f, "avatar_url"),
            Self::AvatarUrl100 => write!(f, "avatar_url_100"),
            Self::AvatarLargeUrl => write!(f, "avatar_large_url"),
            Self::DisplayName => write!(f, "display_name"),
            Self::BioDescription => write!(f, "bio_description"),
            Self::ProfileDeepLink => write!(f, "profile_deep_link"),
            Self::IsVerified => write!(f, "is_verified"),
            Self::FollowerCount => write!(f, "follower_count"),
            Self::FollowingCount => write!(f, "following_count"),
            Self::LikesCount => write!(f, "likes_count"),
            Self::VideoCount => write!(f, "video_count"),
        }
    }
}