open_lark/service/contact/v3/
functional_role.rs

1use crate::core::{
2    api_req::ApiRequest, api_resp::ApiResponseTrait, config::Config, constants::AccessTokenType,
3    endpoints::EndpointBuilder, http::Transport,
4};
5use serde::{Deserialize, Serialize};
6
7/// 角色管理服务
8#[derive(Debug)]
9pub struct FunctionalRoleService {
10    config: Config,
11}
12
13impl FunctionalRoleService {
14    pub fn new(config: Config) -> Self {
15        Self { config }
16    }
17
18    /// 创建角色
19    pub async fn create(
20        &self,
21        req: &CreateFunctionalRoleRequest,
22    ) -> crate::core::SDKResult<CreateFunctionalRoleResponse> {
23        let api_req = ApiRequest {
24            http_method: reqwest::Method::POST,
25            api_path: crate::core::endpoints::contact::CONTACT_V3_FUNCTIONAL_ROLES.to_string(),
26            supported_access_token_types: vec![AccessTokenType::Tenant],
27            body: serde_json::to_vec(req)?,
28            ..Default::default()
29        };
30
31        let resp =
32            Transport::<CreateFunctionalRoleResponse>::request(api_req, &self.config, None).await?;
33        Ok(resp.data.unwrap_or_default())
34    }
35
36    /// 修改角色名称
37    pub async fn update(
38        &self,
39        role_id: &str,
40        req: &UpdateFunctionalRoleRequest,
41    ) -> crate::core::SDKResult<UpdateFunctionalRoleResponse> {
42        let api_req = ApiRequest {
43            http_method: reqwest::Method::PUT,
44            api_path: EndpointBuilder::replace_param(
45                crate::core::endpoints::contact::CONTACT_V3_FUNCTIONAL_ROLE_GET,
46                "role_id",
47                role_id,
48            ),
49            supported_access_token_types: vec![AccessTokenType::Tenant],
50            body: serde_json::to_vec(req)?,
51            ..Default::default()
52        };
53
54        let resp =
55            Transport::<UpdateFunctionalRoleResponse>::request(api_req, &self.config, None).await?;
56        Ok(resp.data.unwrap_or_default())
57    }
58
59    /// 获取单个角色信息
60    pub async fn get(&self, role_id: &str) -> crate::core::SDKResult<GetFunctionalRoleResponse> {
61        let api_req = ApiRequest {
62            http_method: reqwest::Method::GET,
63            api_path: EndpointBuilder::replace_param(
64                crate::core::endpoints::contact::CONTACT_V3_FUNCTIONAL_ROLE_GET,
65                "role_id",
66                role_id,
67            ),
68            supported_access_token_types: vec![AccessTokenType::Tenant],
69            body: Vec::new(),
70            ..Default::default()
71        };
72
73        let resp =
74            Transport::<GetFunctionalRoleResponse>::request(api_req, &self.config, None).await?;
75        Ok(resp.data.unwrap_or_default())
76    }
77
78    /// 获取角色列表
79    pub async fn list(
80        &self,
81        req: &ListFunctionalRolesRequest,
82    ) -> crate::core::SDKResult<ListFunctionalRolesResponse> {
83        let mut api_req = ApiRequest {
84            http_method: reqwest::Method::GET,
85            api_path: crate::core::endpoints::contact::CONTACT_V3_FUNCTIONAL_ROLES.to_string(),
86            supported_access_token_types: vec![AccessTokenType::Tenant],
87            body: Vec::new(),
88            ..Default::default()
89        };
90
91        // 添加查询参数
92        if let Some(page_size) = req.page_size {
93            api_req
94                .query_params
95                .insert("page_size", page_size.to_string());
96        }
97        if let Some(page_token) = &req.page_token {
98            api_req
99                .query_params
100                .insert("page_token", page_token.clone());
101        }
102
103        let resp =
104            Transport::<ListFunctionalRolesResponse>::request(api_req, &self.config, None).await?;
105        Ok(resp.data.unwrap_or_default())
106    }
107
108    /// 删除角色
109    pub async fn delete(
110        &self,
111        role_id: &str,
112    ) -> crate::core::SDKResult<DeleteFunctionalRoleResponse> {
113        let api_req = ApiRequest {
114            http_method: reqwest::Method::DELETE,
115            api_path: EndpointBuilder::replace_param(
116                crate::core::endpoints::contact::CONTACT_V3_FUNCTIONAL_ROLE_GET,
117                "role_id",
118                role_id,
119            ),
120            supported_access_token_types: vec![AccessTokenType::Tenant],
121            body: Vec::new(),
122            ..Default::default()
123        };
124
125        let resp =
126            Transport::<DeleteFunctionalRoleResponse>::request(api_req, &self.config, None).await?;
127        Ok(resp.data.unwrap_or_default())
128    }
129}
130
131#[derive(Debug, Clone, Serialize, Deserialize)]
132pub struct CreateFunctionalRoleRequest {
133    pub role_name: String,
134}
135
136#[derive(Debug, Clone, Serialize, Deserialize, Default)]
137pub struct CreateFunctionalRoleResponse {
138    pub role_id: String,
139}
140
141impl ApiResponseTrait for CreateFunctionalRoleResponse {
142    fn data_format() -> crate::core::api_resp::ResponseFormat {
143        crate::core::api_resp::ResponseFormat::Data
144    }
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
148pub struct UpdateFunctionalRoleRequest {
149    pub role_name: String,
150}
151
152#[derive(Debug, Clone, Serialize, Deserialize, Default)]
153pub struct UpdateFunctionalRoleResponse {}
154
155impl ApiResponseTrait for UpdateFunctionalRoleResponse {
156    fn data_format() -> crate::core::api_resp::ResponseFormat {
157        crate::core::api_resp::ResponseFormat::Data
158    }
159}
160
161#[derive(Debug, Clone, Serialize, Deserialize, Default)]
162pub struct GetFunctionalRoleResponse {
163    pub role: FunctionalRole,
164}
165
166impl ApiResponseTrait for GetFunctionalRoleResponse {
167    fn data_format() -> crate::core::api_resp::ResponseFormat {
168        crate::core::api_resp::ResponseFormat::Data
169    }
170}
171
172#[derive(Debug, Clone, Serialize, Deserialize)]
173pub struct ListFunctionalRolesRequest {
174    /// 分页大小
175    #[serde(skip_serializing_if = "Option::is_none")]
176    pub page_size: Option<i32>,
177    /// 分页标记
178    #[serde(skip_serializing_if = "Option::is_none")]
179    pub page_token: Option<String>,
180}
181
182#[derive(Debug, Clone, Serialize, Deserialize, Default)]
183pub struct ListFunctionalRolesResponse {
184    pub roles: Vec<FunctionalRole>,
185    #[serde(skip_serializing_if = "Option::is_none")]
186    pub has_more: Option<bool>,
187    #[serde(skip_serializing_if = "Option::is_none")]
188    pub page_token: Option<String>,
189}
190
191impl ApiResponseTrait for ListFunctionalRolesResponse {
192    fn data_format() -> crate::core::api_resp::ResponseFormat {
193        crate::core::api_resp::ResponseFormat::Data
194    }
195}
196
197#[derive(Debug, Clone, Serialize, Deserialize, Default)]
198pub struct FunctionalRole {
199    /// 角色ID
200    #[serde(skip_serializing_if = "Option::is_none")]
201    pub role_id: Option<String>,
202    /// 角色名称
203    #[serde(skip_serializing_if = "Option::is_none")]
204    pub role_name: Option<String>,
205}
206
207#[derive(Debug, Clone, Serialize, Deserialize, Default)]
208pub struct DeleteFunctionalRoleResponse {}
209
210impl ApiResponseTrait for DeleteFunctionalRoleResponse {
211    fn data_format() -> crate::core::api_resp::ResponseFormat {
212        crate::core::api_resp::ResponseFormat::Data
213    }
214}
215
216#[cfg(test)]
217mod tests {
218    use super::*;
219    use crate::core::config::Config;
220
221    #[test]
222    fn test_functional_role_service_creation() {
223        let config = Config::default();
224        let service = FunctionalRoleService::new(config);
225        assert!(!format!("{:?}", service).is_empty());
226    }
227
228    #[test]
229    fn test_functional_role_service_creation_with_custom_config() {
230        let config = Config::builder()
231            .app_id("test_app_id")
232            .app_secret("test_secret")
233            .build();
234        let service = FunctionalRoleService::new(config);
235        assert!(!format!("{:?}", service).is_empty());
236    }
237
238    #[test]
239    fn test_create_functional_role_request_construction() {
240        let request = CreateFunctionalRoleRequest {
241            role_name: "测试角色".to_string(),
242        };
243        assert_eq!(request.role_name, "测试角色");
244        assert!(format!("{:?}", request).contains("测试角色"));
245    }
246
247    #[test]
248    fn test_create_functional_role_request_with_empty_name() {
249        let request = CreateFunctionalRoleRequest {
250            role_name: "".to_string(),
251        };
252        assert_eq!(request.role_name, "");
253    }
254
255    #[test]
256    fn test_create_functional_role_request_with_long_name() {
257        let long_name = "a".repeat(500);
258        let request = CreateFunctionalRoleRequest {
259            role_name: long_name.clone(),
260        };
261        assert_eq!(request.role_name, long_name);
262    }
263
264    #[test]
265    fn test_create_functional_role_response_default() {
266        let response = CreateFunctionalRoleResponse::default();
267        assert_eq!(response.role_id, "");
268    }
269
270    #[test]
271    fn test_create_functional_role_response_construction() {
272        let response = CreateFunctionalRoleResponse {
273            role_id: "role_123".to_string(),
274        };
275        assert_eq!(response.role_id, "role_123");
276    }
277
278    #[test]
279    fn test_create_functional_role_response_data_format() {
280        assert_eq!(
281            CreateFunctionalRoleResponse::data_format(),
282            crate::core::api_resp::ResponseFormat::Data
283        );
284    }
285
286    #[test]
287    fn test_update_functional_role_request_construction() {
288        let request = UpdateFunctionalRoleRequest {
289            role_name: "更新后角色".to_string(),
290        };
291        assert_eq!(request.role_name, "更新后角色");
292        assert!(format!("{:?}", request).contains("更新后角色"));
293    }
294
295    #[test]
296    fn test_update_functional_role_request_with_empty_name() {
297        let request = UpdateFunctionalRoleRequest {
298            role_name: "".to_string(),
299        };
300        assert_eq!(request.role_name, "");
301    }
302
303    #[test]
304    fn test_update_functional_role_request_with_long_name() {
305        let long_name = "b".repeat(1000);
306        let request = UpdateFunctionalRoleRequest {
307            role_name: long_name.clone(),
308        };
309        assert_eq!(request.role_name, long_name);
310    }
311
312    #[test]
313    fn test_update_functional_role_response_default() {
314        let response = UpdateFunctionalRoleResponse::default();
315        assert!(!format!("{:?}", response).is_empty());
316    }
317
318    #[test]
319    fn test_update_functional_role_response_data_format() {
320        assert_eq!(
321            UpdateFunctionalRoleResponse::data_format(),
322            crate::core::api_resp::ResponseFormat::Data
323        );
324    }
325
326    #[test]
327    fn test_get_functional_role_response_default() {
328        let response = GetFunctionalRoleResponse::default();
329        assert_eq!(response.role.role_id, None);
330        assert_eq!(response.role.role_name, None);
331    }
332
333    #[test]
334    fn test_get_functional_role_response_construction() {
335        let role = FunctionalRole {
336            role_id: Some("role_456".to_string()),
337            role_name: Some("管理员角色".to_string()),
338        };
339        let response = GetFunctionalRoleResponse { role };
340        assert_eq!(response.role.role_id, Some("role_456".to_string()));
341        assert_eq!(response.role.role_name, Some("管理员角色".to_string()));
342    }
343
344    #[test]
345    fn test_get_functional_role_response_data_format() {
346        assert_eq!(
347            GetFunctionalRoleResponse::data_format(),
348            crate::core::api_resp::ResponseFormat::Data
349        );
350    }
351
352    #[test]
353    fn test_list_functional_roles_request_default() {
354        let request = ListFunctionalRolesRequest {
355            page_size: None,
356            page_token: None,
357        };
358        assert_eq!(request.page_size, None);
359        assert_eq!(request.page_token, None);
360    }
361
362    #[test]
363    fn test_list_functional_roles_request_with_pagination() {
364        let request = ListFunctionalRolesRequest {
365            page_size: Some(50),
366            page_token: Some("token_123".to_string()),
367        };
368        assert_eq!(request.page_size, Some(50));
369        assert_eq!(request.page_token, Some("token_123".to_string()));
370    }
371
372    #[test]
373    fn test_list_functional_roles_request_with_large_page_size() {
374        let request = ListFunctionalRolesRequest {
375            page_size: Some(10000),
376            page_token: Some("large_page_token".to_string()),
377        };
378        assert_eq!(request.page_size, Some(10000));
379        assert_eq!(request.page_token, Some("large_page_token".to_string()));
380    }
381
382    #[test]
383    fn test_list_functional_roles_request_with_zero_page_size() {
384        let request = ListFunctionalRolesRequest {
385            page_size: Some(0),
386            page_token: None,
387        };
388        assert_eq!(request.page_size, Some(0));
389    }
390
391    #[test]
392    fn test_list_functional_roles_request_with_negative_page_size() {
393        let request = ListFunctionalRolesRequest {
394            page_size: Some(-1),
395            page_token: None,
396        };
397        assert_eq!(request.page_size, Some(-1));
398    }
399
400    #[test]
401    fn test_list_functional_roles_request_with_empty_token() {
402        let request = ListFunctionalRolesRequest {
403            page_size: Some(20),
404            page_token: Some("".to_string()),
405        };
406        assert_eq!(request.page_token, Some("".to_string()));
407    }
408
409    #[test]
410    fn test_list_functional_roles_request_with_long_token() {
411        let long_token = "x".repeat(2000);
412        let request = ListFunctionalRolesRequest {
413            page_size: Some(100),
414            page_token: Some(long_token.clone()),
415        };
416        assert_eq!(request.page_token, Some(long_token));
417    }
418
419    #[test]
420    fn test_list_functional_roles_response_default() {
421        let response = ListFunctionalRolesResponse::default();
422        assert_eq!(response.roles.len(), 0);
423        assert_eq!(response.has_more, None);
424        assert_eq!(response.page_token, None);
425    }
426
427    #[test]
428    fn test_list_functional_roles_response_with_roles() {
429        let roles = vec![
430            FunctionalRole {
431                role_id: Some("role_1".to_string()),
432                role_name: Some("角色1".to_string()),
433            },
434            FunctionalRole {
435                role_id: Some("role_2".to_string()),
436                role_name: Some("角色2".to_string()),
437            },
438        ];
439        let response = ListFunctionalRolesResponse {
440            roles,
441            has_more: Some(true),
442            page_token: Some("next_page".to_string()),
443        };
444        assert_eq!(response.roles.len(), 2);
445        assert_eq!(response.has_more, Some(true));
446        assert_eq!(response.page_token, Some("next_page".to_string()));
447    }
448
449    #[test]
450    fn test_list_functional_roles_response_with_large_role_list() {
451        let mut roles = Vec::new();
452        for i in 0..1000 {
453            roles.push(FunctionalRole {
454                role_id: Some(format!("role_{}", i)),
455                role_name: Some(format!("角色{}", i)),
456            });
457        }
458        let response = ListFunctionalRolesResponse {
459            roles,
460            has_more: Some(false),
461            page_token: None,
462        };
463        assert_eq!(response.roles.len(), 1000);
464        assert_eq!(response.has_more, Some(false));
465    }
466
467    #[test]
468    fn test_list_functional_roles_response_data_format() {
469        assert_eq!(
470            ListFunctionalRolesResponse::data_format(),
471            crate::core::api_resp::ResponseFormat::Data
472        );
473    }
474
475    #[test]
476    fn test_functional_role_default() {
477        let role = FunctionalRole::default();
478        assert_eq!(role.role_id, None);
479        assert_eq!(role.role_name, None);
480    }
481
482    #[test]
483    fn test_functional_role_construction() {
484        let role = FunctionalRole {
485            role_id: Some("role_789".to_string()),
486            role_name: Some("超级管理员".to_string()),
487        };
488        assert_eq!(role.role_id, Some("role_789".to_string()));
489        assert_eq!(role.role_name, Some("超级管理员".to_string()));
490    }
491
492    #[test]
493    fn test_functional_role_with_empty_values() {
494        let role = FunctionalRole {
495            role_id: Some("".to_string()),
496            role_name: Some("".to_string()),
497        };
498        assert_eq!(role.role_id, Some("".to_string()));
499        assert_eq!(role.role_name, Some("".to_string()));
500    }
501
502    #[test]
503    fn test_functional_role_with_long_values() {
504        let long_id = "id_".repeat(500);
505        let long_name = "name_".repeat(500);
506        let role = FunctionalRole {
507            role_id: Some(long_id.clone()),
508            role_name: Some(long_name.clone()),
509        };
510        assert_eq!(role.role_id, Some(long_id));
511        assert_eq!(role.role_name, Some(long_name));
512    }
513
514    #[test]
515    fn test_functional_role_partial_none() {
516        let role1 = FunctionalRole {
517            role_id: Some("role_only_id".to_string()),
518            role_name: None,
519        };
520        let role2 = FunctionalRole {
521            role_id: None,
522            role_name: Some("name_only".to_string()),
523        };
524        assert_eq!(role1.role_id, Some("role_only_id".to_string()));
525        assert_eq!(role1.role_name, None);
526        assert_eq!(role2.role_id, None);
527        assert_eq!(role2.role_name, Some("name_only".to_string()));
528    }
529
530    #[test]
531    fn test_delete_functional_role_response_default() {
532        let response = DeleteFunctionalRoleResponse::default();
533        assert!(!format!("{:?}", response).is_empty());
534    }
535
536    #[test]
537    fn test_delete_functional_role_response_data_format() {
538        assert_eq!(
539            DeleteFunctionalRoleResponse::data_format(),
540            crate::core::api_resp::ResponseFormat::Data
541        );
542    }
543
544    #[test]
545    fn test_config_independence() {
546        let config1 = Config::default();
547        let config2 = Config::default();
548        let service1 = FunctionalRoleService::new(config1);
549        let service2 = FunctionalRoleService::new(config2);
550        assert!(!format!("{:?}", service1).is_empty());
551        assert!(!format!("{:?}", service2).is_empty());
552    }
553
554    #[test]
555    fn test_all_structs_debug_trait() {
556        let request1 = CreateFunctionalRoleRequest {
557            role_name: "test".to_string(),
558        };
559        let request2 = UpdateFunctionalRoleRequest {
560            role_name: "test".to_string(),
561        };
562        let request3 = ListFunctionalRolesRequest {
563            page_size: Some(10),
564            page_token: Some("test".to_string()),
565        };
566        let response1 = CreateFunctionalRoleResponse::default();
567        let response2 = UpdateFunctionalRoleResponse::default();
568        let response3 = GetFunctionalRoleResponse::default();
569        let response4 = ListFunctionalRolesResponse::default();
570        let response5 = DeleteFunctionalRoleResponse::default();
571        let role = FunctionalRole::default();
572
573        assert!(format!("{:?}", request1).contains("test"));
574        assert!(format!("{:?}", request2).contains("test"));
575        assert!(format!("{:?}", request3).contains("test"));
576        assert!(!format!("{:?}", response1).is_empty());
577        assert!(!format!("{:?}", response2).is_empty());
578        assert!(!format!("{:?}", response3).is_empty());
579        assert!(!format!("{:?}", response4).is_empty());
580        assert!(!format!("{:?}", response5).is_empty());
581        assert!(!format!("{:?}", role).is_empty());
582    }
583}