Skip to main content

bpi_rs/models/
vip.rs

1use serde::de::{ self, Deserializer, MapAccess, Visitor };
2use serde::{ Deserialize, Serialize };
3use std::fmt;
4
5/// 会员信息
6#[derive(Debug, Clone, Serialize)]
7pub struct Vip {
8    /// 会员类型 0:无 1:月大会员 2:年度及以上大会员
9    /// 别名:vipType | vip_type | type
10    pub vip_type: u8,
11    /// 会员状态 0:无 1:有
12    /// 别名:vipStatus | vip_status | status
13    pub vip_status: u8,
14    /// 会员过期时间 毫秒时间戳
15    /// 别名:vipDueDate | due_date | vip_due_date
16    pub vip_due_date: u64,
17    /// 会员标签
18    pub label: VipLabel,
19    /// 会员昵称颜色 颜色码,一般为#FB7299
20    pub nickname_color: String,
21
22    /// 支付类型 0:未开启自动续费 1:已开启自动续费
23    pub vip_pay_type: Option<u8>,
24
25    /// 大角色类型 1:月度大会员 3:年度大会员 7:十年大会员 15:百年大会员
26    pub role: Option<u8>,
27
28    /// 是否为tv会员
29    pub is_tv_vip: Option<bool>,
30    /// 电视大会员状态 0:未开通
31    pub tv_vip_status: Option<u8>,
32    /// 电视大会员支付类型
33    pub tv_vip_pay_type: Option<u8>,
34    /// 电视大会员过期时间 秒级时间戳
35    pub tv_due_date: Option<u64>,
36
37    /// 用户mid
38    pub mid: Option<u64>,
39    /// 昵称
40    pub name: Option<String>,
41}
42
43/// 会员标签结构体
44#[derive(Default, Debug, Clone, Serialize, Deserialize)]
45pub struct VipLabel {
46    /// 会员类型文案(大会员/年度大会员/十年大会员/百年大会员/最强绿鲤鱼)
47    pub text: String,
48    /// 会员标签(vip/annual_vip/ten_annual_vip/hundred_annual_vip/fools_day_hundred_annual_vip)
49    pub label_theme: String,
50    /// 会员标签文本颜色
51    pub text_color: String,
52    /// 样式
53    pub bg_style: u32,
54    /// 会员标签背景颜色(颜色码,一般为#FB7299)
55    pub bg_color: String,
56}
57
58impl<'de> Deserialize<'de> for Vip {
59    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error> where D: Deserializer<'de> {
60        struct VipVisitor;
61
62        impl<'de> Visitor<'de> for VipVisitor {
63            type Value = Vip;
64
65            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
66                formatter.write_str("a Vip object")
67            }
68
69            fn visit_map<M>(self, mut map: M) -> Result<Vip, M::Error> where M: MapAccess<'de> {
70                let mut vip_type = None;
71                let mut vip_status = None;
72                let mut vip_due_date = None;
73                let mut label = None;
74                let mut nickname_color = None;
75                let mut vip_pay_type = None;
76                let mut role = None;
77                let mut is_tv_vip = None;
78                let mut tv_vip_status = None;
79                let mut tv_vip_pay_type = None;
80                let mut tv_due_date = None;
81                let mut mid = None;
82                let mut name = None;
83
84                while let Some(key) = map.next_key::<String>()? {
85                    match key.as_str() {
86                        "vipType" | "vip_type" | "type" => {
87                            if vip_type.is_some() {
88                                return Err(de::Error::duplicate_field("vip_type"));
89                            }
90                            vip_type = Some(map.next_value()?);
91                        }
92                        "vip_status" | "vipStatus" | "status" => {
93                            if vip_status.is_none() {
94                                vip_status = Some(map.next_value()?);
95                            } else {
96                                let _: serde_json::Value = map.next_value()?;
97                            }
98                        }
99                        "vipDueDate" | "due_date" | "vip_due_date" => {
100                            if vip_due_date.is_none() {
101                                vip_due_date = Some(map.next_value()?);
102                            } else {
103                                let _: serde_json::Value = map.next_value()?;
104                            }
105                        }
106                        "label" => {
107                            if label.is_some() {
108                                return Err(de::Error::duplicate_field("label"));
109                            }
110                            label = Some(map.next_value()?);
111                        }
112                        "nickname_color" => {
113                            if nickname_color.is_some() {
114                                return Err(de::Error::duplicate_field("nickname_color"));
115                            }
116                            nickname_color = Some(map.next_value()?);
117                        }
118                        "vip_pay_type" => {
119                            if vip_pay_type.is_some() {
120                                return Err(de::Error::duplicate_field("vip_pay_type"));
121                            }
122                            vip_pay_type = Some(map.next_value()?);
123                        }
124                        "role" => {
125                            if role.is_some() {
126                                return Err(de::Error::duplicate_field("role"));
127                            }
128                            role = Some(map.next_value()?);
129                        }
130                        "is_tv_vip" => {
131                            if is_tv_vip.is_some() {
132                                return Err(de::Error::duplicate_field("is_tv_vip"));
133                            }
134                            is_tv_vip = Some(map.next_value()?);
135                        }
136                        "tv_vip_status" => {
137                            if tv_vip_status.is_some() {
138                                return Err(de::Error::duplicate_field("tv_vip_status"));
139                            }
140                            tv_vip_status = Some(map.next_value()?);
141                        }
142                        "tv_vip_pay_type" => {
143                            if tv_vip_pay_type.is_some() {
144                                return Err(de::Error::duplicate_field("tv_vip_pay_type"));
145                            }
146                            tv_vip_pay_type = Some(map.next_value()?);
147                        }
148                        "tv_due_date" => {
149                            if tv_due_date.is_some() {
150                                return Err(de::Error::duplicate_field("tv_due_date"));
151                            }
152                            tv_due_date = Some(map.next_value()?);
153                        }
154                        "mid" => {
155                            if mid.is_some() {
156                                return Err(de::Error::duplicate_field("mid"));
157                            }
158                            mid = Some(map.next_value()?);
159                        }
160                        "name" => {
161                            if name.is_some() {
162                                return Err(de::Error::duplicate_field("name"));
163                            }
164                            name = Some(map.next_value()?);
165                        }
166                        _ => {
167                            // 忽略未知字段
168                            let _: serde_json::Value = map.next_value()?;
169                        }
170                    }
171                }
172
173                // 检查必需字段
174                let vip_type = vip_type.ok_or_else(|| de::Error::missing_field("vip_type"))?;
175                let vip_status = vip_status.ok_or_else(|| de::Error::missing_field("vip_status"))?;
176                let vip_due_date = vip_due_date.ok_or_else(||
177                    de::Error::missing_field("vip_due_date")
178                )?;
179                let label = label.ok_or_else(|| de::Error::missing_field("label"))?;
180                let nickname_color = nickname_color.ok_or_else(||
181                    de::Error::missing_field("nickname_color")
182                )?;
183
184                Ok(Vip {
185                    vip_type,
186                    vip_status,
187                    vip_due_date,
188                    label,
189                    nickname_color,
190                    vip_pay_type,
191                    role,
192                    is_tv_vip,
193                    tv_vip_status,
194                    tv_vip_pay_type,
195                    tv_due_date,
196                    mid,
197                    name,
198                })
199            }
200        }
201
202        deserializer.deserialize_map(VipVisitor)
203    }
204}