gewe_core/
login.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4#[serde(rename_all = "camelCase")]
5pub struct GetLoginQrCodeRequest<'a> {
6    /// 设备ID,首次登录可空字符串
7    #[serde(rename = "appId")]
8    pub app_id: &'a str,
9    /// 设备类型:ipad(推荐),mac
10    pub r#type: &'a str,
11    /// 地区ID
12    pub region_id: &'a str,
13    /// 可选代理
14    #[serde(skip_serializing_if = "Option::is_none")]
15    pub proxy_ip: Option<&'a str>,
16    #[serde(skip_serializing_if = "Option::is_none")]
17    pub ttuid: Option<&'a str>,
18    #[serde(skip_serializing_if = "Option::is_none")]
19    pub aid: Option<&'a str>,
20}
21
22#[derive(Debug, Clone, Serialize, Deserialize, Default)]
23#[serde(rename_all = "camelCase")]
24pub struct GetLoginQrCodeResponse {
25    pub qr_data: String,
26    pub qr_img_base64: String,
27    pub uuid: String,
28    pub app_id: String,
29}
30
31#[derive(Debug, Clone, Serialize, Deserialize)]
32#[serde(rename_all = "camelCase")]
33pub struct CheckLoginRequest<'a> {
34    #[serde(rename = "appId")]
35    pub app_id: &'a str,
36    pub uuid: &'a str,
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub proxy_ip: Option<&'a str>,
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub captch_code: Option<&'a str>,
41    #[serde(skip_serializing_if = "Option::is_none")]
42    pub auto_sliding: Option<bool>,
43}
44
45#[derive(Debug, Clone, Serialize, Deserialize, Default)]
46#[serde(rename_all = "camelCase")]
47pub struct CheckLoginResponse {
48    pub uuid: String,
49    #[serde(skip_serializing_if = "Option::is_none")]
50    pub head_img_url: Option<String>,
51    #[serde(skip_serializing_if = "Option::is_none")]
52    pub nick_name: Option<String>,
53    #[serde(skip_serializing_if = "Option::is_none")]
54    pub expired_time: Option<i64>,
55    pub status: i32,
56    #[serde(skip_serializing_if = "Option::is_none")]
57    pub login_info: Option<LoginInfo>,
58}
59
60#[derive(Debug, Clone, Serialize, Deserialize, Default)]
61#[serde(rename_all = "camelCase")]
62pub struct LoginInfo {
63    #[serde(skip_serializing_if = "Option::is_none")]
64    pub uin: Option<i64>,
65    #[serde(skip_serializing_if = "Option::is_none")]
66    pub wxid: Option<String>,
67    #[serde(skip_serializing_if = "Option::is_none")]
68    pub nick_name: Option<String>,
69    #[serde(skip_serializing_if = "Option::is_none")]
70    pub mobile: Option<String>,
71    #[serde(skip_serializing_if = "Option::is_none")]
72    pub alias: Option<String>,
73}
74
75#[derive(Debug, Clone, Serialize)]
76#[serde(rename_all = "camelCase")]
77pub struct DialogLoginRequest<'a> {
78    #[serde(rename = "appId")]
79    pub app_id: &'a str,
80    #[serde(rename = "regionId")]
81    pub region_id: &'a str,
82    #[serde(rename = "proxyIp", skip_serializing_if = "Option::is_none")]
83    pub proxy_ip: Option<&'a str>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub aid: Option<&'a str>,
86}
87
88#[derive(Debug, Clone, Serialize, Deserialize, Default)]
89#[serde(rename_all = "camelCase")]
90pub struct DialogLoginResponse {
91    #[serde(rename = "appId")]
92    pub app_id: String,
93    pub uuid: String,
94}
95
96#[derive(Debug, Clone, Serialize)]
97#[serde(rename_all = "camelCase")]
98pub struct LoginByAccountRequest<'a> {
99    #[serde(rename = "appId")]
100    pub app_id: &'a str,
101    #[serde(rename = "proxyIp")]
102    pub proxy_ip: &'a str,
103    #[serde(rename = "regionId")]
104    pub region_id: &'a str,
105    pub account: &'a str,
106    pub password: &'a str,
107    pub step: i32,
108}
109
110#[derive(Debug, Clone, Serialize, Deserialize, Default)]
111#[serde(rename_all = "camelCase")]
112pub struct LoginByAccountResponse {
113    #[serde(rename = "appId", skip_serializing_if = "Option::is_none")]
114    pub app_id: Option<String>,
115    #[serde(rename = "base64Img", skip_serializing_if = "Option::is_none")]
116    pub base64_img: Option<String>,
117    #[serde(skip_serializing_if = "Option::is_none")]
118    pub uuid: Option<String>,
119    #[serde(rename = "headImgUrl", skip_serializing_if = "Option::is_none")]
120    pub head_img_url: Option<String>,
121    #[serde(rename = "nickName", skip_serializing_if = "Option::is_none")]
122    pub nick_name: Option<String>,
123    #[serde(rename = "expiredTime", skip_serializing_if = "Option::is_none")]
124    pub expired_time: Option<i64>,
125    #[serde(skip_serializing_if = "Option::is_none")]
126    pub status: Option<i32>,
127    #[serde(skip_serializing_if = "Option::is_none")]
128    pub login_info: Option<LoginInfo>,
129}
130
131#[derive(Debug, Clone, Serialize)]
132#[serde(rename_all = "camelCase")]
133pub struct SetCallbackRequest<'a> {
134    pub token: &'a str,
135    #[serde(rename = "callbackUrl")]
136    pub callback_url: &'a str,
137}
138
139#[derive(Debug, Clone, Serialize)]
140#[serde(rename_all = "camelCase")]
141pub struct ChangeMacToIpadRequest<'a> {
142    #[serde(rename = "appId")]
143    pub app_id: &'a str,
144}
145
146#[derive(Debug, Clone, Serialize)]
147#[serde(rename_all = "camelCase")]
148pub struct CheckOnlineRequest<'a> {
149    #[serde(rename = "appId")]
150    pub app_id: &'a str,
151}
152
153pub type CheckOnlineResponse = bool;
154
155#[derive(Debug, Clone, Serialize)]
156#[serde(rename_all = "camelCase")]
157pub struct ReconnectionRequest<'a> {
158    #[serde(rename = "appId")]
159    pub app_id: &'a str,
160}
161
162#[derive(Debug, Clone, Serialize, Deserialize, Default)]
163#[serde(rename_all = "camelCase")]
164pub struct ReconnectionResponse {
165    pub uuid: String,
166    #[serde(rename = "headImgUrl", skip_serializing_if = "Option::is_none")]
167    pub head_img_url: Option<String>,
168    #[serde(rename = "nickName", skip_serializing_if = "Option::is_none")]
169    pub nick_name: Option<String>,
170    #[serde(rename = "expiredTime", skip_serializing_if = "Option::is_none")]
171    pub expired_time: Option<i64>,
172    pub status: i32,
173    #[serde(skip_serializing_if = "Option::is_none")]
174    pub login_info: Option<LoginInfo>,
175}
176
177#[derive(Debug, Clone, Serialize)]
178#[serde(rename_all = "camelCase")]
179pub struct LogoutRequest<'a> {
180    #[serde(rename = "appId")]
181    pub app_id: &'a str,
182}
183
184#[cfg(test)]
185mod tests {
186    use super::*;
187
188    #[test]
189    fn test_get_login_qr_code_response_default() {
190        let resp = GetLoginQrCodeResponse::default();
191        assert_eq!(resp.qr_data, "");
192        assert_eq!(resp.qr_img_base64, "");
193        assert_eq!(resp.uuid, "");
194        assert_eq!(resp.app_id, "");
195    }
196
197    #[test]
198    fn test_get_login_qr_code_response_deserialization() {
199        let json = r#"{
200            "qrData": "test_qr_data",
201            "qrImgBase64": "base64_image",
202            "uuid": "test_uuid",
203            "appId": "test_app_id"
204        }"#;
205        let resp: GetLoginQrCodeResponse = serde_json::from_str(json).unwrap();
206        assert_eq!(resp.qr_data, "test_qr_data");
207        assert_eq!(resp.qr_img_base64, "base64_image");
208        assert_eq!(resp.uuid, "test_uuid");
209        assert_eq!(resp.app_id, "test_app_id");
210    }
211
212    #[test]
213    fn test_check_login_response_default() {
214        let resp = CheckLoginResponse::default();
215        assert_eq!(resp.uuid, "");
216        assert_eq!(resp.status, 0);
217        assert_eq!(resp.head_img_url, None);
218        assert_eq!(resp.nick_name, None);
219    }
220
221    #[test]
222    fn test_check_login_response_with_login_info() {
223        let json = r#"{
224            "uuid": "test_uuid",
225            "status": 1,
226            "headImgUrl": "http://example.com/avatar.jpg",
227            "nickName": "TestUser",
228            "expiredTime": 1234567890,
229            "loginInfo": {
230                "uin": 123456,
231                "wxid": "test_wxid",
232                "nickName": "TestUser",
233                "mobile": "1234567890",
234                "alias": "test_alias"
235            }
236        }"#;
237        let resp: CheckLoginResponse = serde_json::from_str(json).unwrap();
238        assert_eq!(resp.uuid, "test_uuid");
239        assert_eq!(resp.status, 1);
240        assert_eq!(
241            resp.head_img_url,
242            Some("http://example.com/avatar.jpg".to_string())
243        );
244        assert_eq!(resp.nick_name, Some("TestUser".to_string()));
245        assert_eq!(resp.expired_time, Some(1234567890));
246        assert!(resp.login_info.is_some());
247
248        let login_info = resp.login_info.unwrap();
249        assert_eq!(login_info.uin, Some(123456));
250        assert_eq!(login_info.wxid, Some("test_wxid".to_string()));
251        assert_eq!(login_info.nick_name, Some("TestUser".to_string()));
252        assert_eq!(login_info.mobile, Some("1234567890".to_string()));
253        assert_eq!(login_info.alias, Some("test_alias".to_string()));
254    }
255
256    #[test]
257    fn test_login_info_default() {
258        let info = LoginInfo::default();
259        assert_eq!(info.uin, None);
260        assert_eq!(info.wxid, None);
261        assert_eq!(info.nick_name, None);
262        assert_eq!(info.mobile, None);
263        assert_eq!(info.alias, None);
264    }
265
266    #[test]
267    fn test_dialog_login_response_default() {
268        let resp = DialogLoginResponse::default();
269        assert_eq!(resp.app_id, "");
270        assert_eq!(resp.uuid, "");
271    }
272
273    #[test]
274    fn test_dialog_login_response_deserialization() {
275        let json = r#"{
276            "appId": "test_app",
277            "uuid": "test_uuid"
278        }"#;
279        let resp: DialogLoginResponse = serde_json::from_str(json).unwrap();
280        assert_eq!(resp.app_id, "test_app");
281        assert_eq!(resp.uuid, "test_uuid");
282    }
283
284    #[test]
285    fn test_login_by_account_response_default() {
286        let resp = LoginByAccountResponse::default();
287        assert_eq!(resp.app_id, None);
288        assert_eq!(resp.base64_img, None);
289        assert_eq!(resp.uuid, None);
290        assert_eq!(resp.status, None);
291    }
292
293    #[test]
294    fn test_login_by_account_response_deserialization() {
295        let json = r#"{
296            "appId": "test_app",
297            "base64Img": "base64_data",
298            "uuid": "test_uuid",
299            "headImgUrl": "http://example.com/avatar.jpg",
300            "nickName": "TestUser",
301            "expiredTime": 1234567890,
302            "status": 1
303        }"#;
304        let resp: LoginByAccountResponse = serde_json::from_str(json).unwrap();
305        assert_eq!(resp.app_id, Some("test_app".to_string()));
306        assert_eq!(resp.base64_img, Some("base64_data".to_string()));
307        assert_eq!(resp.uuid, Some("test_uuid".to_string()));
308        assert_eq!(
309            resp.head_img_url,
310            Some("http://example.com/avatar.jpg".to_string())
311        );
312        assert_eq!(resp.nick_name, Some("TestUser".to_string()));
313        assert_eq!(resp.expired_time, Some(1234567890));
314        assert_eq!(resp.status, Some(1));
315    }
316
317    #[test]
318    fn test_reconnection_response_default() {
319        let resp = ReconnectionResponse::default();
320        assert_eq!(resp.uuid, "");
321        assert_eq!(resp.status, 0);
322        assert_eq!(resp.head_img_url, None);
323    }
324
325    #[test]
326    fn test_reconnection_response_deserialization() {
327        let json = r#"{
328            "uuid": "test_uuid",
329            "status": 1,
330            "headImgUrl": "http://example.com/avatar.jpg",
331            "nickName": "TestUser",
332            "expiredTime": 1234567890
333        }"#;
334        let resp: ReconnectionResponse = serde_json::from_str(json).unwrap();
335        assert_eq!(resp.uuid, "test_uuid");
336        assert_eq!(resp.status, 1);
337        assert_eq!(
338            resp.head_img_url,
339            Some("http://example.com/avatar.jpg".to_string())
340        );
341        assert_eq!(resp.nick_name, Some("TestUser".to_string()));
342        assert_eq!(resp.expired_time, Some(1234567890));
343    }
344
345    #[test]
346    fn test_get_login_qr_code_request_serialization() {
347        let req = GetLoginQrCodeRequest {
348            app_id: "test_app",
349            r#type: "ipad",
350            region_id: "cn",
351            proxy_ip: Some("127.0.0.1"),
352            ttuid: None,
353            aid: None,
354        };
355        let json = serde_json::to_string(&req).unwrap();
356        assert!(json.contains("test_app"));
357        assert!(json.contains("ipad"));
358        assert!(json.contains("cn"));
359        assert!(json.contains("127.0.0.1"));
360    }
361
362    #[test]
363    fn test_check_login_request_serialization() {
364        let req = CheckLoginRequest {
365            app_id: "test_app",
366            uuid: "test_uuid",
367            proxy_ip: None,
368            captch_code: None,
369            auto_sliding: Some(true),
370        };
371        let json = serde_json::to_string(&req).unwrap();
372        assert!(json.contains("test_app"));
373        assert!(json.contains("test_uuid"));
374        assert!(json.contains("true"));
375    }
376
377    #[test]
378    fn test_dialog_login_request_serialization() {
379        let req = DialogLoginRequest {
380            app_id: "test_app",
381            region_id: "cn",
382            proxy_ip: Some("127.0.0.1"),
383            aid: None,
384        };
385        let json = serde_json::to_string(&req).unwrap();
386        assert!(json.contains("test_app"));
387        assert!(json.contains("cn"));
388        assert!(json.contains("127.0.0.1"));
389    }
390
391    #[test]
392    fn test_login_by_account_request_serialization() {
393        let req = LoginByAccountRequest {
394            app_id: "test_app",
395            proxy_ip: "127.0.0.1",
396            region_id: "cn",
397            account: "test_account",
398            password: "test_password",
399            step: 1,
400        };
401        let json = serde_json::to_string(&req).unwrap();
402        assert!(json.contains("test_app"));
403        assert!(json.contains("127.0.0.1"));
404        assert!(json.contains("test_account"));
405        assert!(json.contains("test_password"));
406    }
407
408    #[test]
409    fn test_set_callback_request_serialization() {
410        let req = SetCallbackRequest {
411            token: "test_token",
412            callback_url: "http://example.com/callback",
413        };
414        let json = serde_json::to_string(&req).unwrap();
415        assert!(json.contains("test_token"));
416        assert!(json.contains("http://example.com/callback"));
417    }
418
419    #[test]
420    fn test_change_mac_to_ipad_request_serialization() {
421        let req = ChangeMacToIpadRequest { app_id: "test_app" };
422        let json = serde_json::to_string(&req).unwrap();
423        assert!(json.contains("test_app"));
424    }
425
426    #[test]
427    fn test_check_online_request_serialization() {
428        let req = CheckOnlineRequest { app_id: "test_app" };
429        let json = serde_json::to_string(&req).unwrap();
430        assert!(json.contains("test_app"));
431    }
432
433    #[test]
434    fn test_reconnection_request_serialization() {
435        let req = ReconnectionRequest { app_id: "test_app" };
436        let json = serde_json::to_string(&req).unwrap();
437        assert!(json.contains("test_app"));
438    }
439
440    #[test]
441    fn test_logout_request_serialization() {
442        let req = LogoutRequest { app_id: "test_app" };
443        let json = serde_json::to_string(&req).unwrap();
444        assert!(json.contains("test_app"));
445    }
446}