open_lark/service/cloud_docs/permission/member/
batch_create.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
15#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
17#[serde(rename_all = "snake_case")]
18#[derive(Default)]
19pub enum Permission {
20 FullAccess,
22 Edit,
24 #[default]
26 View,
27 Comment,
29}
30
31#[derive(Debug, Serialize, Deserialize, Clone)]
33pub struct Collaborator {
34 pub member_type: String,
36 pub member_id: String,
38 pub perm: Permission,
40}
41
42#[derive(Debug, Serialize, Default, Clone)]
44pub struct BatchCreatePermissionMemberRequest {
45 #[serde(skip)]
46 api_request: ApiRequest,
47 #[serde(skip)]
49 token: String,
50 #[serde(skip)]
52 obj_type: String,
53 members: Vec<Collaborator>,
55 #[serde(skip_serializing_if = "Option::is_none")]
57 need_notification: Option<bool>,
58}
59
60impl BatchCreatePermissionMemberRequest {
61 pub fn builder() -> BatchCreatePermissionMemberRequestBuilder {
62 BatchCreatePermissionMemberRequestBuilder::default()
63 }
64
65 pub fn new(token: impl ToString, obj_type: impl ToString, members: Vec<Collaborator>) -> Self {
66 Self {
67 token: token.to_string(),
68 obj_type: obj_type.to_string(),
69 members,
70 ..Default::default()
71 }
72 }
73}
74
75#[derive(Default)]
76pub struct BatchCreatePermissionMemberRequestBuilder {
77 request: BatchCreatePermissionMemberRequest,
78}
79
80impl BatchCreatePermissionMemberRequestBuilder {
81 pub fn token(mut self, token: impl ToString) -> Self {
83 self.request.token = token.to_string();
84 self
85 }
86
87 pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
89 self.request.obj_type = obj_type.to_string();
90 self
91 }
92
93 pub fn as_doc(mut self) -> Self {
95 self.request.obj_type = "doc".to_string();
96 self
97 }
98
99 pub fn as_sheet(mut self) -> Self {
101 self.request.obj_type = "sheet".to_string();
102 self
103 }
104
105 pub fn as_bitable(mut self) -> Self {
107 self.request.obj_type = "bitable".to_string();
108 self
109 }
110
111 pub fn as_wiki(mut self) -> Self {
113 self.request.obj_type = "wiki".to_string();
114 self
115 }
116
117 pub fn members(mut self, members: Vec<Collaborator>) -> Self {
119 self.request.members = members;
120 self
121 }
122
123 pub fn add_member(mut self, member: Collaborator) -> Self {
125 self.request.members.push(member);
126 self
127 }
128
129 pub fn add_user(mut self, user_id: impl ToString, permission: Permission) -> Self {
131 self.request.members.push(Collaborator {
132 member_type: "user".to_string(),
133 member_id: user_id.to_string(),
134 perm: permission,
135 });
136 self
137 }
138
139 pub fn add_chat(mut self, chat_id: impl ToString, permission: Permission) -> Self {
141 self.request.members.push(Collaborator {
142 member_type: "chat".to_string(),
143 member_id: chat_id.to_string(),
144 perm: permission,
145 });
146 self
147 }
148
149 pub fn add_department(mut self, department_id: impl ToString, permission: Permission) -> Self {
151 self.request.members.push(Collaborator {
152 member_type: "department".to_string(),
153 member_id: department_id.to_string(),
154 perm: permission,
155 });
156 self
157 }
158
159 pub fn need_notification(mut self, need: bool) -> Self {
161 self.request.need_notification = Some(need);
162 self
163 }
164
165 pub fn with_notification(mut self) -> Self {
167 self.request.need_notification = Some(true);
168 self
169 }
170
171 pub fn without_notification(mut self) -> Self {
173 self.request.need_notification = Some(false);
174 self
175 }
176
177 pub fn build(mut self) -> BatchCreatePermissionMemberRequest {
178 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
179 self.request
180 }
181}
182
183crate::impl_executable_builder_owned!(
184 BatchCreatePermissionMemberRequestBuilder,
185 crate::service::cloud_docs::permission::PermissionService,
186 BatchCreatePermissionMemberRequest,
187 BaseResponse<BatchCreatePermissionMemberResponse>,
188 batch_create_member
189);
190
191#[derive(Debug, Deserialize)]
193pub struct MemberResult {
194 pub member_type: String,
196 pub member_id: String,
198 pub perm: Permission,
200 pub result: String,
202 pub code: Option<i32>,
204 pub msg: Option<String>,
206}
207
208#[derive(Debug, Deserialize)]
210pub struct BatchCreatePermissionMemberResponse {
211 pub members: Vec<MemberResult>,
213}
214
215impl ApiResponseTrait for BatchCreatePermissionMemberResponse {
216 fn data_format() -> ResponseFormat {
217 ResponseFormat::Data
218 }
219}
220
221pub async fn batch_create_permission_member(
223 request: BatchCreatePermissionMemberRequest,
224 config: &Config,
225 option: Option<RequestOption>,
226) -> SDKResult<BaseResponse<BatchCreatePermissionMemberResponse>> {
227 let mut api_req = request.api_request;
228 api_req.http_method = Method::POST;
229 api_req.api_path = format!(
230 "{}?type={}",
231 EndpointBuilder::replace_param(
232 DRIVE_V1_PERMISSIONS_MEMBERS_BATCH_CREATE,
233 "token",
234 &request.token
235 ),
236 request.obj_type
237 );
238
239 if let Some(need_notification) = request.need_notification {
241 api_req.api_path = format!(
242 "{}&need_notification={}",
243 api_req.api_path, need_notification
244 );
245 }
246
247 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
248
249 let api_resp = Transport::request(api_req, config, option).await?;
250 Ok(api_resp)
251}
252
253impl Permission {
254 pub fn level(&self) -> u8 {
256 match self {
257 Permission::View => 1,
258 Permission::Comment => 2,
259 Permission::Edit => 3,
260 Permission::FullAccess => 4,
261 }
262 }
263
264 pub fn can_edit(&self) -> bool {
266 matches!(self, Permission::Edit | Permission::FullAccess)
267 }
268
269 pub fn can_comment(&self) -> bool {
271 !matches!(self, Permission::View)
272 }
273
274 pub fn is_owner(&self) -> bool {
276 matches!(self, Permission::FullAccess)
277 }
278
279 pub fn description(&self) -> &'static str {
281 match self {
282 Permission::FullAccess => "所有者",
283 Permission::Edit => "编辑者",
284 Permission::Comment => "评论者",
285 Permission::View => "阅读者",
286 }
287 }
288}
289
290impl MemberResult {
291 pub fn is_success(&self) -> bool {
293 self.result == "success"
294 }
295
296 pub fn has_error(&self) -> bool {
298 self.code.is_some() || self.msg.is_some()
299 }
300
301 pub fn error_message(&self) -> Option<String> {
303 if let (Some(code), Some(msg)) = (self.code, &self.msg) {
304 Some(format!("错误码: {code}, 错误信息: {msg}"))
305 } else if let Some(msg) = &self.msg {
306 Some(msg.clone())
307 } else {
308 self.code.map(|code| format!("错误码: {code}"))
309 }
310 }
311}
312
313impl BatchCreatePermissionMemberResponse {
314 pub fn success_count(&self) -> usize {
316 self.members
317 .iter()
318 .filter(|member| member.is_success())
319 .count()
320 }
321
322 pub fn failed_count(&self) -> usize {
324 self.members
325 .iter()
326 .filter(|member| !member.is_success())
327 .count()
328 }
329
330 pub fn successful_members(&self) -> Vec<&MemberResult> {
332 self.members
333 .iter()
334 .filter(|member| member.is_success())
335 .collect()
336 }
337
338 pub fn failed_members(&self) -> Vec<&MemberResult> {
340 self.members
341 .iter()
342 .filter(|member| !member.is_success())
343 .collect()
344 }
345
346 pub fn summary(&self) -> String {
348 format!(
349 "总计: {}, 成功: {}, 失败: {}",
350 self.members.len(),
351 self.success_count(),
352 self.failed_count()
353 )
354 }
355}
356
357#[cfg(test)]
358#[allow(unused_variables, unused_unsafe)]
359mod tests {
360 use super::*;
361
362 #[test]
363 fn test_batch_create_permission_member_request_builder() {
364 let request = BatchCreatePermissionMemberRequest::builder()
365 .token("doccnxxxxxx")
366 .as_doc()
367 .add_user("user123", Permission::Edit)
368 .add_chat("chat456", Permission::View)
369 .with_notification()
370 .build();
371
372 assert_eq!(request.token, "doccnxxxxxx");
373 assert_eq!(request.obj_type, "doc");
374 assert_eq!(request.members.len(), 2);
375 assert_eq!(request.need_notification, Some(true));
376 }
377
378 #[test]
379 fn test_permission_methods() {
380 assert!(Permission::Edit.can_edit());
381 assert!(Permission::FullAccess.can_edit());
382 assert!(!Permission::View.can_edit());
383
384 assert!(Permission::Edit.can_comment());
385 assert!(!Permission::View.can_comment());
386
387 assert!(Permission::FullAccess.is_owner());
388 assert!(!Permission::Edit.is_owner());
389
390 assert_eq!(Permission::FullAccess.level(), 4);
391 assert_eq!(Permission::View.level(), 1);
392 }
393}