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 endpoints::{cloud_docs::*, EndpointBuilder},
10 http::Transport,
11 req_option::RequestOption,
12 SDKResult,
13};
14
15use super::batch_create::Permission;
16
17#[derive(Debug, Serialize, Default, Clone)]
19pub struct ListPermissionMembersRequest {
20 #[serde(skip)]
21 api_request: ApiRequest,
22 #[serde(skip)]
24 token: String,
25 #[serde(skip)]
27 obj_type: String,
28 #[serde(skip_serializing_if = "Option::is_none")]
30 page_size: Option<i32>,
31 #[serde(skip_serializing_if = "Option::is_none")]
33 page_token: Option<String>,
34}
35
36impl ListPermissionMembersRequest {
37 pub fn builder() -> ListPermissionMembersRequestBuilder {
38 ListPermissionMembersRequestBuilder::default()
39 }
40
41 pub fn new(token: impl ToString, obj_type: impl ToString) -> Self {
42 Self {
43 token: token.to_string(),
44 obj_type: obj_type.to_string(),
45 ..Default::default()
46 }
47 }
48}
49
50#[derive(Default)]
51pub struct ListPermissionMembersRequestBuilder {
52 request: ListPermissionMembersRequest,
53}
54
55impl ListPermissionMembersRequestBuilder {
56 pub fn token(mut self, token: impl ToString) -> Self {
58 self.request.token = token.to_string();
59 self
60 }
61
62 pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
64 self.request.obj_type = obj_type.to_string();
65 self
66 }
67
68 pub fn as_doc(mut self) -> Self {
70 self.request.obj_type = "doc".to_string();
71 self
72 }
73
74 pub fn as_sheet(mut self) -> Self {
76 self.request.obj_type = "sheet".to_string();
77 self
78 }
79
80 pub fn as_bitable(mut self) -> Self {
82 self.request.obj_type = "bitable".to_string();
83 self
84 }
85
86 pub fn as_wiki(mut self) -> Self {
88 self.request.obj_type = "wiki".to_string();
89 self
90 }
91
92 pub fn page_size(mut self, page_size: i32) -> Self {
94 self.request.page_size = Some(page_size);
95 self
96 }
97
98 pub fn page_token(mut self, page_token: impl ToString) -> Self {
100 self.request.page_token = Some(page_token.to_string());
101 self
102 }
103
104 pub fn build(mut self) -> ListPermissionMembersRequest {
105 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
106 self.request
107 }
108}
109
110crate::impl_executable_builder_owned!(
111 ListPermissionMembersRequestBuilder,
112 crate::service::cloud_docs::permission::PermissionService,
113 ListPermissionMembersRequest,
114 BaseResponse<ListPermissionMembersResponse>,
115 list_members
116);
117
118#[derive(Debug, Deserialize)]
120pub struct PermissionMember {
121 pub member_type: String,
123 pub member_id: String,
125 pub perm: Permission,
127 pub name: Option<String>,
129 pub avatar: Option<String>,
131 pub type_str: Option<String>,
133 pub is_inherited: Option<bool>,
135 pub inherit_info: Option<String>,
137}
138
139#[derive(Debug, Deserialize)]
141pub struct ListPermissionMembersResponse {
142 pub members: Vec<PermissionMember>,
144 pub has_more: bool,
146 pub page_token: Option<String>,
148}
149
150impl ApiResponseTrait for ListPermissionMembersResponse {
151 fn data_format() -> ResponseFormat {
152 ResponseFormat::Data
153 }
154}
155
156pub async fn list_permission_members(
158 request: ListPermissionMembersRequest,
159 config: &Config,
160 option: Option<RequestOption>,
161) -> SDKResult<BaseResponse<ListPermissionMembersResponse>> {
162 let mut api_req = request.api_request;
163 api_req.http_method = Method::GET;
164 api_req.api_path = format!(
165 "{}?type={}",
166 EndpointBuilder::replace_param(DRIVE_V1_PERMISSIONS_MEMBERS, "token", &request.token),
167 request.obj_type
168 );
169
170 let mut query_params = Vec::new();
172 if let Some(page_size) = request.page_size {
173 query_params.push(format!("page_size={page_size}"));
174 }
175 if let Some(page_token) = request.page_token {
176 query_params.push(format!("page_token={page_token}"));
177 }
178
179 if !query_params.is_empty() {
180 api_req.api_path = format!("{}&{}", api_req.api_path, query_params.join("&"));
181 }
182
183 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
184
185 let api_resp = Transport::request(api_req, config, option).await?;
186 Ok(api_resp)
187}
188
189impl PermissionMember {
190 pub fn display_name(&self) -> String {
192 self.name
193 .as_ref()
194 .cloned()
195 .unwrap_or_else(|| self.member_id.clone())
196 }
197
198 pub fn is_user(&self) -> bool {
200 self.member_type == "user"
201 }
202
203 pub fn is_chat(&self) -> bool {
205 self.member_type == "chat"
206 }
207
208 pub fn is_department(&self) -> bool {
210 self.member_type == "department"
211 }
212
213 pub fn can_edit(&self) -> bool {
215 self.perm.can_edit()
216 }
217
218 pub fn is_owner(&self) -> bool {
220 self.perm.is_owner()
221 }
222
223 pub fn has_inherited_permission(&self) -> bool {
225 self.is_inherited.unwrap_or(false)
226 }
227
228 pub fn permission_description(&self) -> String {
230 let mut desc = self.perm.description().to_string();
231
232 if self.has_inherited_permission() {
233 desc.push_str(" (继承)");
234 if let Some(inherit_info) = &self.inherit_info {
235 desc.push_str(&format!(" 来源: {inherit_info}"));
236 }
237 }
238
239 desc
240 }
241
242 pub fn member_type_description(&self) -> String {
244 self.type_str
245 .as_ref()
246 .cloned()
247 .unwrap_or_else(|| match self.member_type.as_str() {
248 "user" => "用户".to_string(),
249 "chat" => "群组".to_string(),
250 "department" => "部门".to_string(),
251 _ => "未知".to_string(),
252 })
253 }
254
255 pub fn summary(&self) -> String {
257 format!(
258 "{} ({}) - {} - {}",
259 self.display_name(),
260 self.member_id,
261 self.member_type_description(),
262 self.permission_description()
263 )
264 }
265}
266
267impl ListPermissionMembersResponse {
268 pub fn count(&self) -> usize {
270 self.members.len()
271 }
272
273 pub fn is_empty(&self) -> bool {
275 self.members.is_empty()
276 }
277
278 pub fn owners(&self) -> Vec<&PermissionMember> {
280 self.members
281 .iter()
282 .filter(|member| member.is_owner())
283 .collect()
284 }
285
286 pub fn editors(&self) -> Vec<&PermissionMember> {
288 self.members
289 .iter()
290 .filter(|member| matches!(member.perm, Permission::Edit))
291 .collect()
292 }
293
294 pub fn commenters(&self) -> Vec<&PermissionMember> {
296 self.members
297 .iter()
298 .filter(|member| matches!(member.perm, Permission::Comment))
299 .collect()
300 }
301
302 pub fn viewers(&self) -> Vec<&PermissionMember> {
304 self.members
305 .iter()
306 .filter(|member| matches!(member.perm, Permission::View))
307 .collect()
308 }
309
310 pub fn group_by_permission(&self) -> std::collections::HashMap<String, Vec<&PermissionMember>> {
312 let mut groups = std::collections::HashMap::new();
313
314 for member in &self.members {
315 let perm_key = member.perm.description().to_string();
316 groups.entry(perm_key).or_insert_with(Vec::new).push(member);
317 }
318
319 groups
320 }
321
322 pub fn group_by_member_type(
324 &self,
325 ) -> std::collections::HashMap<String, Vec<&PermissionMember>> {
326 let mut groups = std::collections::HashMap::new();
327
328 for member in &self.members {
329 groups
330 .entry(member.member_type.clone())
331 .or_insert_with(Vec::new)
332 .push(member);
333 }
334
335 groups
336 }
337
338 pub fn inherited_members(&self) -> Vec<&PermissionMember> {
340 self.members
341 .iter()
342 .filter(|member| member.has_inherited_permission())
343 .collect()
344 }
345
346 pub fn direct_members(&self) -> Vec<&PermissionMember> {
348 self.members
349 .iter()
350 .filter(|member| !member.has_inherited_permission())
351 .collect()
352 }
353
354 pub fn permission_summary(&self) -> String {
356 let owners = self.owners().len();
357 let editors = self.editors().len();
358 let commenters = self.commenters().len();
359 let viewers = self.viewers().len();
360
361 format!(
362 "协作者总数: {}, 所有者: {}, 编辑者: {}, 评论者: {}, 阅读者: {}",
363 self.count(),
364 owners,
365 editors,
366 commenters,
367 viewers
368 )
369 }
370}
371
372#[cfg(test)]
373#[allow(unused_variables, unused_unsafe)]
374mod tests {
375 use super::*;
376
377 #[test]
378 fn test_list_permission_members_request_builder() {
379 let request = ListPermissionMembersRequest::builder()
380 .token("doccnxxxxxx")
381 .as_doc()
382 .page_size(20)
383 .page_token("token123")
384 .build();
385
386 assert_eq!(request.token, "doccnxxxxxx");
387 assert_eq!(request.obj_type, "doc");
388 assert_eq!(request.page_size, Some(20));
389 assert_eq!(request.page_token, Some("token123".to_string()));
390 }
391
392 #[test]
393 fn test_list_permission_members_new() {
394 let request = ListPermissionMembersRequest::new("doccnxxxxxx", "doc");
395 assert_eq!(request.token, "doccnxxxxxx");
396 assert_eq!(request.obj_type, "doc");
397 }
398}