gewe_core/contact/
info.rs

1use serde::{Deserialize, Serialize};
2
3#[derive(Debug, Clone, Serialize, Deserialize)]
4#[serde(rename_all = "camelCase")]
5pub struct FetchContactsListRequest<'a> {
6    #[serde(rename = "appId")]
7    pub app_id: &'a str,
8}
9
10#[derive(Debug, Clone, Serialize, Deserialize, Default)]
11#[serde(rename_all = "camelCase")]
12pub struct FetchContactsListResponse {
13    pub friends: Vec<String>,
14    pub chatrooms: Vec<String>,
15    pub ghs: Vec<String>,
16}
17
18#[derive(Debug, Clone, Serialize, Deserialize)]
19#[serde(rename_all = "camelCase")]
20pub struct FetchContactsListCacheRequest<'a> {
21    #[serde(rename = "appId")]
22    pub app_id: &'a str,
23}
24
25pub type FetchContactsListCacheResponse = ();
26
27#[derive(Debug, Clone, Serialize, Deserialize)]
28#[serde(rename_all = "camelCase")]
29pub struct SearchContactsRequest<'a> {
30    #[serde(rename = "appId")]
31    pub app_id: &'a str,
32    #[serde(rename = "contactsInfo")]
33    pub contacts_info: &'a str,
34}
35
36#[derive(Debug, Clone, Serialize, Deserialize, Default)]
37#[serde(rename_all = "camelCase")]
38pub struct SearchContactsResponse {
39    pub v3: String,
40    #[serde(rename = "nickName")]
41    pub nick_name: String,
42    pub sex: i32,
43    #[serde(default, skip_serializing_if = "Option::is_none")]
44    pub signature: Option<String>,
45    #[serde(rename = "bigHeadImgUrl")]
46    pub big_head_img_url: String,
47    #[serde(rename = "smallHeadImgUrl")]
48    pub small_head_img_url: String,
49    #[serde(default, skip_serializing_if = "Option::is_none")]
50    pub v4: Option<String>,
51}
52
53#[derive(Debug, Clone, Serialize, Deserialize)]
54#[serde(rename_all = "camelCase")]
55pub struct GetContactBriefInfoRequest<'a> {
56    #[serde(rename = "appId")]
57    pub app_id: &'a str,
58    pub wxids: Vec<&'a str>,
59}
60
61#[derive(Debug, Clone, Serialize, Deserialize, Default)]
62#[serde(rename_all = "camelCase")]
63pub struct ContactBriefInfo {
64    #[serde(rename = "userName")]
65    pub user_name: String,
66    #[serde(rename = "nickName")]
67    pub nick_name: String,
68    #[serde(rename = "pyInitial")]
69    pub py_initial: String,
70    #[serde(rename = "quanPin")]
71    pub quan_pin: String,
72    pub sex: i32,
73    pub remark: String,
74    #[serde(rename = "remarkPyInitial")]
75    pub remark_py_initial: String,
76    #[serde(rename = "remarkQuanPin")]
77    pub remark_quan_pin: String,
78    #[serde(default, skip_serializing_if = "Option::is_none")]
79    pub signature: Option<String>,
80    pub alias: String,
81    #[serde(rename = "snsBgImg", default, skip_serializing_if = "Option::is_none")]
82    pub sns_bg_img: Option<String>,
83    pub country: String,
84    #[serde(rename = "bigHeadImgUrl")]
85    pub big_head_img_url: String,
86    #[serde(rename = "smallHeadImgUrl")]
87    pub small_head_img_url: String,
88    #[serde(default, skip_serializing_if = "Option::is_none")]
89    pub description: Option<String>,
90    #[serde(
91        rename = "cardImgUrl",
92        default,
93        skip_serializing_if = "Option::is_none"
94    )]
95    pub card_img_url: Option<String>,
96    #[serde(rename = "labelList")]
97    pub label_list: String,
98    pub province: String,
99    pub city: String,
100    #[serde(
101        rename = "phoneNumList",
102        default,
103        skip_serializing_if = "Option::is_none"
104    )]
105    pub phone_num_list: Option<String>,
106}
107
108pub type GetContactBriefInfoResponse = Vec<ContactBriefInfo>;
109
110#[derive(Debug, Clone, Serialize, Deserialize)]
111#[serde(rename_all = "camelCase")]
112pub struct GetContactDetailInfoRequest<'a> {
113    #[serde(rename = "appId")]
114    pub app_id: &'a str,
115    pub wxids: Vec<&'a str>,
116}
117
118#[derive(Debug, Clone, Serialize, Deserialize, Default)]
119#[serde(rename_all = "camelCase")]
120pub struct ContactDetailInfo {
121    #[serde(rename = "userName")]
122    pub user_name: String,
123    #[serde(rename = "nickName")]
124    pub nick_name: String,
125    #[serde(rename = "pyInitial", default, skip_serializing_if = "Option::is_none")]
126    pub py_initial: Option<String>,
127    #[serde(rename = "quanPin")]
128    pub quan_pin: String,
129    pub sex: i32,
130    #[serde(default, skip_serializing_if = "Option::is_none")]
131    pub remark: Option<String>,
132    #[serde(
133        rename = "remarkPyInitial",
134        default,
135        skip_serializing_if = "Option::is_none"
136    )]
137    pub remark_py_initial: Option<String>,
138    #[serde(
139        rename = "remarkQuanPin",
140        default,
141        skip_serializing_if = "Option::is_none"
142    )]
143    pub remark_quan_pin: Option<String>,
144    pub signature: String,
145    pub alias: String,
146    #[serde(rename = "snsBgImg")]
147    pub sns_bg_img: String,
148    pub country: String,
149    #[serde(rename = "bigHeadImgUrl")]
150    pub big_head_img_url: String,
151    #[serde(rename = "smallHeadImgUrl")]
152    pub small_head_img_url: String,
153    #[serde(default, skip_serializing_if = "Option::is_none")]
154    pub description: Option<String>,
155    #[serde(
156        rename = "cardImgUrl",
157        default,
158        skip_serializing_if = "Option::is_none"
159    )]
160    pub card_img_url: Option<String>,
161    #[serde(rename = "labelList", default, skip_serializing_if = "Option::is_none")]
162    pub label_list: Option<String>,
163    #[serde(default, skip_serializing_if = "Option::is_none")]
164    pub province: Option<String>,
165    #[serde(default, skip_serializing_if = "Option::is_none")]
166    pub city: Option<String>,
167    #[serde(
168        rename = "phoneNumList",
169        default,
170        skip_serializing_if = "Option::is_none"
171    )]
172    pub phone_num_list: Option<String>,
173}
174
175pub type GetContactDetailInfoResponse = Vec<ContactDetailInfo>;
176
177#[derive(Debug, Clone, Serialize, Deserialize)]
178#[serde(rename_all = "camelCase")]
179pub struct GetPhoneAddressListRequest<'a> {
180    #[serde(rename = "appId")]
181    pub app_id: &'a str,
182    #[serde(default, skip_serializing_if = "Option::is_none")]
183    pub phones: Option<Vec<&'a str>>,
184}
185
186#[derive(Debug, Clone, Serialize, Deserialize, Default)]
187#[serde(rename_all = "camelCase")]
188pub struct PhoneContact {
189    #[serde(rename = "userName")]
190    pub user_name: String,
191    #[serde(default, skip_serializing_if = "Option::is_none")]
192    pub v4: Option<String>,
193    #[serde(rename = "nickName", default, skip_serializing_if = "Option::is_none")]
194    pub nick_name: Option<String>,
195    pub sex: i32,
196    #[serde(rename = "phoneMd5")]
197    pub phone_md5: String,
198    pub signature: String,
199    #[serde(default, skip_serializing_if = "Option::is_none")]
200    pub alias: Option<String>,
201    pub country: String,
202    #[serde(rename = "bigHeadImgUrl")]
203    pub big_head_img_url: String,
204    #[serde(rename = "smallHeadImgUrl")]
205    pub small_head_img_url: String,
206    pub province: String,
207    pub city: String,
208    #[serde(rename = "personalCard")]
209    pub personal_card: i32,
210}
211
212pub type GetPhoneAddressListResponse = Vec<PhoneContact>;
213
214#[derive(Debug, Clone, Serialize, Deserialize)]
215#[serde(rename_all = "camelCase")]
216pub struct CheckRelationRequest<'a> {
217    #[serde(rename = "appId")]
218    pub app_id: &'a str,
219    pub wxids: Vec<&'a str>,
220}
221
222#[derive(Debug, Clone, Serialize, Deserialize, Default)]
223#[serde(rename_all = "camelCase")]
224pub struct ContactRelationStatus {
225    pub wxid: String,
226    pub relation: i32,
227}
228
229pub type CheckRelationResponse = Vec<ContactRelationStatus>;
230
231#[cfg(test)]
232mod tests {
233    use super::*;
234
235    #[test]
236    fn test_fetch_contacts_list_response_default() {
237        let resp = FetchContactsListResponse::default();
238        assert!(resp.friends.is_empty());
239        assert!(resp.chatrooms.is_empty());
240        assert!(resp.ghs.is_empty());
241    }
242
243    #[test]
244    fn test_fetch_contacts_list_response_deserialization() {
245        let json = r#"{
246            "friends": ["wxid1", "wxid2"],
247            "chatrooms": ["room1", "room2"],
248            "ghs": ["gh1"]
249        }"#;
250        let resp: FetchContactsListResponse = serde_json::from_str(json).unwrap();
251        assert_eq!(resp.friends, vec!["wxid1", "wxid2"]);
252        assert_eq!(resp.chatrooms, vec!["room1", "room2"]);
253        assert_eq!(resp.ghs, vec!["gh1"]);
254    }
255
256    #[test]
257    fn test_search_contacts_response_default() {
258        let resp = SearchContactsResponse::default();
259        assert_eq!(resp.v3, "");
260        assert_eq!(resp.nick_name, "");
261        assert_eq!(resp.sex, 0);
262        assert_eq!(resp.signature, None);
263    }
264
265    #[test]
266    fn test_search_contacts_response_deserialization() {
267        let json = r#"{
268            "v3": "test_v3",
269            "nickName": "TestUser",
270            "sex": 1,
271            "signature": "Hello World",
272            "bigHeadImgUrl": "http://example.com/big.jpg",
273            "smallHeadImgUrl": "http://example.com/small.jpg",
274            "v4": "test_v4"
275        }"#;
276        let resp: SearchContactsResponse = serde_json::from_str(json).unwrap();
277        assert_eq!(resp.v3, "test_v3");
278        assert_eq!(resp.nick_name, "TestUser");
279        assert_eq!(resp.sex, 1);
280        assert_eq!(resp.signature, Some("Hello World".to_string()));
281        assert_eq!(resp.big_head_img_url, "http://example.com/big.jpg");
282        assert_eq!(resp.small_head_img_url, "http://example.com/small.jpg");
283        assert_eq!(resp.v4, Some("test_v4".to_string()));
284    }
285
286    #[test]
287    fn test_contact_brief_info_default() {
288        let info = ContactBriefInfo::default();
289        assert_eq!(info.user_name, "");
290        assert_eq!(info.nick_name, "");
291        assert_eq!(info.sex, 0);
292        assert_eq!(info.remark, "");
293    }
294
295    #[test]
296    fn test_contact_brief_info_deserialization() {
297        let json = r#"{
298            "userName": "wxid_test",
299            "nickName": "TestUser",
300            "pyInitial": "TU",
301            "quanPin": "testuser",
302            "sex": 1,
303            "remark": "My Friend",
304            "remarkPyInitial": "MF",
305            "remarkQuanPin": "myfriend",
306            "signature": "Hello",
307            "alias": "test_alias",
308            "country": "CN",
309            "bigHeadImgUrl": "http://example.com/big.jpg",
310            "smallHeadImgUrl": "http://example.com/small.jpg",
311            "labelList": "label1,label2",
312            "province": "Beijing",
313            "city": "Beijing"
314        }"#;
315        let info: ContactBriefInfo = serde_json::from_str(json).unwrap();
316        assert_eq!(info.user_name, "wxid_test");
317        assert_eq!(info.nick_name, "TestUser");
318        assert_eq!(info.py_initial, "TU");
319        assert_eq!(info.sex, 1);
320        assert_eq!(info.remark, "My Friend");
321        assert_eq!(info.alias, "test_alias");
322        assert_eq!(info.country, "CN");
323        assert_eq!(info.province, "Beijing");
324        assert_eq!(info.city, "Beijing");
325    }
326
327    #[test]
328    fn test_contact_detail_info_default() {
329        let info = ContactDetailInfo::default();
330        assert_eq!(info.user_name, "");
331        assert_eq!(info.nick_name, "");
332        assert_eq!(info.sex, 0);
333        assert_eq!(info.signature, "");
334    }
335
336    #[test]
337    fn test_contact_detail_info_deserialization() {
338        let json = r#"{
339            "userName": "wxid_test",
340            "nickName": "TestUser",
341            "quanPin": "testuser",
342            "sex": 1,
343            "signature": "Hello World",
344            "alias": "test_alias",
345            "snsBgImg": "http://example.com/bg.jpg",
346            "country": "CN",
347            "bigHeadImgUrl": "http://example.com/big.jpg",
348            "smallHeadImgUrl": "http://example.com/small.jpg"
349        }"#;
350        let info: ContactDetailInfo = serde_json::from_str(json).unwrap();
351        assert_eq!(info.user_name, "wxid_test");
352        assert_eq!(info.nick_name, "TestUser");
353        assert_eq!(info.quan_pin, "testuser");
354        assert_eq!(info.sex, 1);
355        assert_eq!(info.signature, "Hello World");
356        assert_eq!(info.alias, "test_alias");
357        assert_eq!(info.country, "CN");
358    }
359
360    #[test]
361    fn test_phone_contact_default() {
362        let contact = PhoneContact::default();
363        assert_eq!(contact.user_name, "");
364        assert_eq!(contact.sex, 0);
365        assert_eq!(contact.phone_md5, "");
366        assert_eq!(contact.signature, "");
367    }
368
369    #[test]
370    fn test_phone_contact_deserialization() {
371        let json = r#"{
372            "userName": "wxid_test",
373            "sex": 1,
374            "phoneMd5": "abc123",
375            "signature": "Hello",
376            "country": "CN",
377            "bigHeadImgUrl": "http://example.com/big.jpg",
378            "smallHeadImgUrl": "http://example.com/small.jpg",
379            "province": "Beijing",
380            "city": "Beijing",
381            "personalCard": 1
382        }"#;
383        let contact: PhoneContact = serde_json::from_str(json).unwrap();
384        assert_eq!(contact.user_name, "wxid_test");
385        assert_eq!(contact.sex, 1);
386        assert_eq!(contact.phone_md5, "abc123");
387        assert_eq!(contact.signature, "Hello");
388        assert_eq!(contact.country, "CN");
389        assert_eq!(contact.personal_card, 1);
390    }
391
392    #[test]
393    fn test_contact_relation_status_default() {
394        let status = ContactRelationStatus::default();
395        assert_eq!(status.wxid, "");
396        assert_eq!(status.relation, 0);
397    }
398
399    #[test]
400    fn test_contact_relation_status_deserialization() {
401        let json = r#"{
402            "wxid": "wxid_test",
403            "relation": 1
404        }"#;
405        let status: ContactRelationStatus = serde_json::from_str(json).unwrap();
406        assert_eq!(status.wxid, "wxid_test");
407        assert_eq!(status.relation, 1);
408    }
409
410    #[test]
411    fn test_fetch_contacts_list_request_serialization() {
412        let req = FetchContactsListRequest { app_id: "test_app" };
413        let json = serde_json::to_string(&req).unwrap();
414        assert!(json.contains("test_app"));
415    }
416
417    #[test]
418    fn test_search_contacts_request_serialization() {
419        let req = SearchContactsRequest {
420            app_id: "test_app",
421            contacts_info: "wxid_test",
422        };
423        let json = serde_json::to_string(&req).unwrap();
424        assert!(json.contains("test_app"));
425        assert!(json.contains("wxid_test"));
426    }
427
428    #[test]
429    fn test_get_contact_brief_info_request_serialization() {
430        let req = GetContactBriefInfoRequest {
431            app_id: "test_app",
432            wxids: vec!["wxid1", "wxid2"],
433        };
434        let json = serde_json::to_string(&req).unwrap();
435        assert!(json.contains("test_app"));
436        assert!(json.contains("wxid1"));
437        assert!(json.contains("wxid2"));
438    }
439
440    #[test]
441    fn test_get_phone_address_list_request_serialization() {
442        let req = GetPhoneAddressListRequest {
443            app_id: "test_app",
444            phones: Some(vec!["12345678901", "12345678902"]),
445        };
446        let json = serde_json::to_string(&req).unwrap();
447        assert!(json.contains("test_app"));
448        assert!(json.contains("12345678901"));
449    }
450
451    #[test]
452    fn test_check_relation_request_serialization() {
453        let req = CheckRelationRequest {
454            app_id: "test_app",
455            wxids: vec!["wxid1", "wxid2"],
456        };
457        let json = serde_json::to_string(&req).unwrap();
458        assert!(json.contains("test_app"));
459        assert!(json.contains("wxid1"));
460    }
461}