open_lark/service/cloud_docs/permission/member/
list.rs1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::core::{
5 api_req::ApiRequest,
6 api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
7 config::Config,
8 constants::AccessTokenType,
9 http::Transport,
10 req_option::RequestOption,
11 SDKResult,
12};
13
14use super::batch_create::Permission;
15
16#[derive(Debug, Serialize, Default, Clone)]
18pub struct ListPermissionMembersRequest {
19 #[serde(skip)]
20 api_request: ApiRequest,
21 #[serde(skip)]
23 token: String,
24 #[serde(skip)]
26 obj_type: String,
27 #[serde(skip_serializing_if = "Option::is_none")]
29 page_size: Option<i32>,
30 #[serde(skip_serializing_if = "Option::is_none")]
32 page_token: Option<String>,
33}
34
35impl ListPermissionMembersRequest {
36 pub fn builder() -> ListPermissionMembersRequestBuilder {
37 ListPermissionMembersRequestBuilder::default()
38 }
39
40 pub fn new(token: impl ToString, obj_type: impl ToString) -> Self {
41 Self {
42 token: token.to_string(),
43 obj_type: obj_type.to_string(),
44 ..Default::default()
45 }
46 }
47}
48
49#[derive(Default)]
50pub struct ListPermissionMembersRequestBuilder {
51 request: ListPermissionMembersRequest,
52}
53
54impl ListPermissionMembersRequestBuilder {
55 pub fn token(mut self, token: impl ToString) -> Self {
57 self.request.token = token.to_string();
58 self
59 }
60
61 pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
63 self.request.obj_type = obj_type.to_string();
64 self
65 }
66
67 pub fn as_doc(mut self) -> Self {
69 self.request.obj_type = "doc".to_string();
70 self
71 }
72
73 pub fn as_sheet(mut self) -> Self {
75 self.request.obj_type = "sheet".to_string();
76 self
77 }
78
79 pub fn as_bitable(mut self) -> Self {
81 self.request.obj_type = "bitable".to_string();
82 self
83 }
84
85 pub fn as_wiki(mut self) -> Self {
87 self.request.obj_type = "wiki".to_string();
88 self
89 }
90
91 pub fn page_size(mut self, page_size: i32) -> Self {
93 self.request.page_size = Some(page_size);
94 self
95 }
96
97 pub fn page_token(mut self, page_token: impl ToString) -> Self {
99 self.request.page_token = Some(page_token.to_string());
100 self
101 }
102
103 pub fn build(mut self) -> ListPermissionMembersRequest {
104 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
105 self.request
106 }
107}
108
109crate::impl_executable_builder_owned!(
110 ListPermissionMembersRequestBuilder,
111 crate::service::cloud_docs::permission::PermissionService,
112 ListPermissionMembersRequest,
113 BaseResponse<ListPermissionMembersResponse>,
114 list_members
115);
116
117#[derive(Debug, Deserialize)]
119pub struct PermissionMember {
120 pub member_type: String,
122 pub member_id: String,
124 pub perm: Permission,
126 pub name: Option<String>,
128 pub avatar: Option<String>,
130 pub type_str: Option<String>,
132 pub is_inherited: Option<bool>,
134 pub inherit_info: Option<String>,
136}
137
138#[derive(Debug, Deserialize)]
140pub struct ListPermissionMembersResponse {
141 pub members: Vec<PermissionMember>,
143 pub has_more: bool,
145 pub page_token: Option<String>,
147}
148
149impl ApiResponseTrait for ListPermissionMembersResponse {
150 fn data_format() -> ResponseFormat {
151 ResponseFormat::Data
152 }
153}
154
155pub async fn list_permission_members(
157 request: ListPermissionMembersRequest,
158 config: &Config,
159 option: Option<RequestOption>,
160) -> SDKResult<BaseResponse<ListPermissionMembersResponse>> {
161 let mut api_req = request.api_request;
162 api_req.http_method = Method::GET;
163 api_req.api_path = format!(
164 "/open-apis/drive/v1/permissions/{}/members?type={}",
165 request.token, request.obj_type
166 );
167
168 let mut query_params = Vec::new();
170 if let Some(page_size) = request.page_size {
171 query_params.push(format!("page_size={page_size}"));
172 }
173 if let Some(page_token) = request.page_token {
174 query_params.push(format!("page_token={page_token}"));
175 }
176
177 if !query_params.is_empty() {
178 api_req.api_path = format!("{}&{}", api_req.api_path, query_params.join("&"));
179 }
180
181 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
182
183 let api_resp = Transport::request(api_req, config, option).await?;
184 Ok(api_resp)
185}
186
187impl PermissionMember {
188 pub fn display_name(&self) -> String {
190 self.name
191 .as_ref()
192 .cloned()
193 .unwrap_or_else(|| self.member_id.clone())
194 }
195
196 pub fn is_user(&self) -> bool {
198 self.member_type == "user"
199 }
200
201 pub fn is_chat(&self) -> bool {
203 self.member_type == "chat"
204 }
205
206 pub fn is_department(&self) -> bool {
208 self.member_type == "department"
209 }
210
211 pub fn can_edit(&self) -> bool {
213 self.perm.can_edit()
214 }
215
216 pub fn is_owner(&self) -> bool {
218 self.perm.is_owner()
219 }
220
221 pub fn has_inherited_permission(&self) -> bool {
223 self.is_inherited.unwrap_or(false)
224 }
225
226 pub fn permission_description(&self) -> String {
228 let mut desc = self.perm.description().to_string();
229
230 if self.has_inherited_permission() {
231 desc.push_str(" (继承)");
232 if let Some(inherit_info) = &self.inherit_info {
233 desc.push_str(&format!(" 来源: {inherit_info}"));
234 }
235 }
236
237 desc
238 }
239
240 pub fn member_type_description(&self) -> String {
242 self.type_str
243 .as_ref()
244 .cloned()
245 .unwrap_or_else(|| match self.member_type.as_str() {
246 "user" => "用户".to_string(),
247 "chat" => "群组".to_string(),
248 "department" => "部门".to_string(),
249 _ => "未知".to_string(),
250 })
251 }
252
253 pub fn summary(&self) -> String {
255 format!(
256 "{} ({}) - {} - {}",
257 self.display_name(),
258 self.member_id,
259 self.member_type_description(),
260 self.permission_description()
261 )
262 }
263}
264
265impl ListPermissionMembersResponse {
266 pub fn count(&self) -> usize {
268 self.members.len()
269 }
270
271 pub fn is_empty(&self) -> bool {
273 self.members.is_empty()
274 }
275
276 pub fn owners(&self) -> Vec<&PermissionMember> {
278 self.members
279 .iter()
280 .filter(|member| member.is_owner())
281 .collect()
282 }
283
284 pub fn editors(&self) -> Vec<&PermissionMember> {
286 self.members
287 .iter()
288 .filter(|member| matches!(member.perm, Permission::Edit))
289 .collect()
290 }
291
292 pub fn commenters(&self) -> Vec<&PermissionMember> {
294 self.members
295 .iter()
296 .filter(|member| matches!(member.perm, Permission::Comment))
297 .collect()
298 }
299
300 pub fn viewers(&self) -> Vec<&PermissionMember> {
302 self.members
303 .iter()
304 .filter(|member| matches!(member.perm, Permission::View))
305 .collect()
306 }
307
308 pub fn group_by_permission(&self) -> std::collections::HashMap<String, Vec<&PermissionMember>> {
310 let mut groups = std::collections::HashMap::new();
311
312 for member in &self.members {
313 let perm_key = member.perm.description().to_string();
314 groups.entry(perm_key).or_insert_with(Vec::new).push(member);
315 }
316
317 groups
318 }
319
320 pub fn group_by_member_type(
322 &self,
323 ) -> std::collections::HashMap<String, Vec<&PermissionMember>> {
324 let mut groups = std::collections::HashMap::new();
325
326 for member in &self.members {
327 groups
328 .entry(member.member_type.clone())
329 .or_insert_with(Vec::new)
330 .push(member);
331 }
332
333 groups
334 }
335
336 pub fn inherited_members(&self) -> Vec<&PermissionMember> {
338 self.members
339 .iter()
340 .filter(|member| member.has_inherited_permission())
341 .collect()
342 }
343
344 pub fn direct_members(&self) -> Vec<&PermissionMember> {
346 self.members
347 .iter()
348 .filter(|member| !member.has_inherited_permission())
349 .collect()
350 }
351
352 pub fn permission_summary(&self) -> String {
354 let owners = self.owners().len();
355 let editors = self.editors().len();
356 let commenters = self.commenters().len();
357 let viewers = self.viewers().len();
358
359 format!(
360 "协作者总数: {}, 所有者: {}, 编辑者: {}, 评论者: {}, 阅读者: {}",
361 self.count(),
362 owners,
363 editors,
364 commenters,
365 viewers
366 )
367 }
368}
369
370#[cfg(test)]
371mod tests {
372 use super::*;
373
374 #[test]
375 fn test_list_permission_members_request_builder() {
376 let request = ListPermissionMembersRequest::builder()
377 .token("doccnxxxxxx")
378 .as_doc()
379 .page_size(20)
380 .page_token("token123")
381 .build();
382
383 assert_eq!(request.token, "doccnxxxxxx");
384 assert_eq!(request.obj_type, "doc");
385 assert_eq!(request.page_size, Some(20));
386 assert_eq!(request.page_token, Some("token123".to_string()));
387 }
388
389 #[test]
390 fn test_list_permission_members_new() {
391 let request = ListPermissionMembersRequest::new("doccnxxxxxx", "doc");
392 assert_eq!(request.token, "doccnxxxxxx");
393 assert_eq!(request.obj_type, "doc");
394 }
395}