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 http::Transport,
10 req_option::RequestOption,
11 SDKResult,
12};
13
14#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
16#[serde(rename_all = "snake_case")]
17#[derive(Default)]
18pub enum Permission {
19 FullAccess,
21 Edit,
23 #[default]
25 View,
26 Comment,
28}
29
30#[derive(Debug, Serialize, Deserialize, Clone)]
32pub struct Collaborator {
33 pub member_type: String,
35 pub member_id: String,
37 pub perm: Permission,
39}
40
41#[derive(Debug, Serialize, Default, Clone)]
43pub struct BatchCreatePermissionMemberRequest {
44 #[serde(skip)]
45 api_request: ApiRequest,
46 #[serde(skip)]
48 token: String,
49 #[serde(skip)]
51 obj_type: String,
52 members: Vec<Collaborator>,
54 #[serde(skip_serializing_if = "Option::is_none")]
56 need_notification: Option<bool>,
57}
58
59impl BatchCreatePermissionMemberRequest {
60 pub fn builder() -> BatchCreatePermissionMemberRequestBuilder {
61 BatchCreatePermissionMemberRequestBuilder::default()
62 }
63
64 pub fn new(token: impl ToString, obj_type: impl ToString, members: Vec<Collaborator>) -> Self {
65 Self {
66 token: token.to_string(),
67 obj_type: obj_type.to_string(),
68 members,
69 ..Default::default()
70 }
71 }
72}
73
74#[derive(Default)]
75pub struct BatchCreatePermissionMemberRequestBuilder {
76 request: BatchCreatePermissionMemberRequest,
77}
78
79impl BatchCreatePermissionMemberRequestBuilder {
80 pub fn token(mut self, token: impl ToString) -> Self {
82 self.request.token = token.to_string();
83 self
84 }
85
86 pub fn obj_type(mut self, obj_type: impl ToString) -> Self {
88 self.request.obj_type = obj_type.to_string();
89 self
90 }
91
92 pub fn as_doc(mut self) -> Self {
94 self.request.obj_type = "doc".to_string();
95 self
96 }
97
98 pub fn as_sheet(mut self) -> Self {
100 self.request.obj_type = "sheet".to_string();
101 self
102 }
103
104 pub fn as_bitable(mut self) -> Self {
106 self.request.obj_type = "bitable".to_string();
107 self
108 }
109
110 pub fn as_wiki(mut self) -> Self {
112 self.request.obj_type = "wiki".to_string();
113 self
114 }
115
116 pub fn members(mut self, members: Vec<Collaborator>) -> Self {
118 self.request.members = members;
119 self
120 }
121
122 pub fn add_member(mut self, member: Collaborator) -> Self {
124 self.request.members.push(member);
125 self
126 }
127
128 pub fn add_user(mut self, user_id: impl ToString, permission: Permission) -> Self {
130 self.request.members.push(Collaborator {
131 member_type: "user".to_string(),
132 member_id: user_id.to_string(),
133 perm: permission,
134 });
135 self
136 }
137
138 pub fn add_chat(mut self, chat_id: impl ToString, permission: Permission) -> Self {
140 self.request.members.push(Collaborator {
141 member_type: "chat".to_string(),
142 member_id: chat_id.to_string(),
143 perm: permission,
144 });
145 self
146 }
147
148 pub fn add_department(mut self, department_id: impl ToString, permission: Permission) -> Self {
150 self.request.members.push(Collaborator {
151 member_type: "department".to_string(),
152 member_id: department_id.to_string(),
153 perm: permission,
154 });
155 self
156 }
157
158 pub fn need_notification(mut self, need: bool) -> Self {
160 self.request.need_notification = Some(need);
161 self
162 }
163
164 pub fn with_notification(mut self) -> Self {
166 self.request.need_notification = Some(true);
167 self
168 }
169
170 pub fn without_notification(mut self) -> Self {
172 self.request.need_notification = Some(false);
173 self
174 }
175
176 pub fn build(mut self) -> BatchCreatePermissionMemberRequest {
177 self.request.api_request.body = serde_json::to_vec(&self.request).unwrap();
178 self.request
179 }
180}
181
182crate::impl_executable_builder_owned!(
183 BatchCreatePermissionMemberRequestBuilder,
184 crate::service::cloud_docs::permission::PermissionService,
185 BatchCreatePermissionMemberRequest,
186 BaseResponse<BatchCreatePermissionMemberResponse>,
187 batch_create_member
188);
189
190#[derive(Debug, Deserialize)]
192pub struct MemberResult {
193 pub member_type: String,
195 pub member_id: String,
197 pub perm: Permission,
199 pub result: String,
201 pub code: Option<i32>,
203 pub msg: Option<String>,
205}
206
207#[derive(Debug, Deserialize)]
209pub struct BatchCreatePermissionMemberResponse {
210 pub members: Vec<MemberResult>,
212}
213
214impl ApiResponseTrait for BatchCreatePermissionMemberResponse {
215 fn data_format() -> ResponseFormat {
216 ResponseFormat::Data
217 }
218}
219
220pub async fn batch_create_permission_member(
222 request: BatchCreatePermissionMemberRequest,
223 config: &Config,
224 option: Option<RequestOption>,
225) -> SDKResult<BaseResponse<BatchCreatePermissionMemberResponse>> {
226 let mut api_req = request.api_request;
227 api_req.http_method = Method::POST;
228 api_req.api_path = format!(
229 "/open-apis/drive/v1/permissions/{}/members/batch_create?type={}",
230 request.token, request.obj_type
231 );
232
233 if let Some(need_notification) = request.need_notification {
235 api_req.api_path = format!(
236 "{}&need_notification={}",
237 api_req.api_path, need_notification
238 );
239 }
240
241 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
242
243 let api_resp = Transport::request(api_req, config, option).await?;
244 Ok(api_resp)
245}
246
247impl Permission {
248 pub fn level(&self) -> u8 {
250 match self {
251 Permission::View => 1,
252 Permission::Comment => 2,
253 Permission::Edit => 3,
254 Permission::FullAccess => 4,
255 }
256 }
257
258 pub fn can_edit(&self) -> bool {
260 matches!(self, Permission::Edit | Permission::FullAccess)
261 }
262
263 pub fn can_comment(&self) -> bool {
265 !matches!(self, Permission::View)
266 }
267
268 pub fn is_owner(&self) -> bool {
270 matches!(self, Permission::FullAccess)
271 }
272
273 pub fn description(&self) -> &'static str {
275 match self {
276 Permission::FullAccess => "所有者",
277 Permission::Edit => "编辑者",
278 Permission::Comment => "评论者",
279 Permission::View => "阅读者",
280 }
281 }
282}
283
284impl MemberResult {
285 pub fn is_success(&self) -> bool {
287 self.result == "success"
288 }
289
290 pub fn has_error(&self) -> bool {
292 self.code.is_some() || self.msg.is_some()
293 }
294
295 pub fn error_message(&self) -> Option<String> {
297 if let (Some(code), Some(msg)) = (self.code, &self.msg) {
298 Some(format!("错误码: {code}, 错误信息: {msg}"))
299 } else if let Some(msg) = &self.msg {
300 Some(msg.clone())
301 } else {
302 self.code.map(|code| format!("错误码: {code}"))
303 }
304 }
305}
306
307impl BatchCreatePermissionMemberResponse {
308 pub fn success_count(&self) -> usize {
310 self.members
311 .iter()
312 .filter(|member| member.is_success())
313 .count()
314 }
315
316 pub fn failed_count(&self) -> usize {
318 self.members
319 .iter()
320 .filter(|member| !member.is_success())
321 .count()
322 }
323
324 pub fn successful_members(&self) -> Vec<&MemberResult> {
326 self.members
327 .iter()
328 .filter(|member| member.is_success())
329 .collect()
330 }
331
332 pub fn failed_members(&self) -> Vec<&MemberResult> {
334 self.members
335 .iter()
336 .filter(|member| !member.is_success())
337 .collect()
338 }
339
340 pub fn summary(&self) -> String {
342 format!(
343 "总计: {}, 成功: {}, 失败: {}",
344 self.members.len(),
345 self.success_count(),
346 self.failed_count()
347 )
348 }
349}
350
351#[cfg(test)]
352mod tests {
353 use super::*;
354
355 #[test]
356 fn test_batch_create_permission_member_request_builder() {
357 let request = BatchCreatePermissionMemberRequest::builder()
358 .token("doccnxxxxxx")
359 .as_doc()
360 .add_user("user123", Permission::Edit)
361 .add_chat("chat456", Permission::View)
362 .with_notification()
363 .build();
364
365 assert_eq!(request.token, "doccnxxxxxx");
366 assert_eq!(request.obj_type, "doc");
367 assert_eq!(request.members.len(), 2);
368 assert_eq!(request.need_notification, Some(true));
369 }
370
371 #[test]
372 fn test_permission_methods() {
373 assert!(Permission::Edit.can_edit());
374 assert!(Permission::FullAccess.can_edit());
375 assert!(!Permission::View.can_edit());
376
377 assert!(Permission::Edit.can_comment());
378 assert!(!Permission::View.can_comment());
379
380 assert!(Permission::FullAccess.is_owner());
381 assert!(!Permission::Edit.is_owner());
382
383 assert_eq!(Permission::FullAccess.level(), 4);
384 assert_eq!(Permission::View.level(), 1);
385 }
386}