open_lark/service/cloud_docs/drive/v2/
explorer.rs1use std::fmt::Debug;
2
3use log::error;
4use reqwest::Method;
5use serde::{Deserialize, Serialize};
6
7use crate::{
8 core::{
9 api_req::ApiRequest,
10 api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
11 config::Config,
12 constants::AccessTokenType,
13 http::Transport,
14 req_option::RequestOption,
15 SDKResult,
16 },
17 impl_executable_builder_owned,
18};
19
20pub struct ExplorerService {
21 config: Config,
22}
23
24impl ExplorerService {
25 pub fn new(config: Config) -> Self {
26 Self { config }
27 }
28
29 pub async fn root_folder_meta(
33 &self,
34 option: Option<RequestOption>,
35 ) -> SDKResult<BaseResponse<ExplorerRootMeta>> {
36 let api_req = ApiRequest {
37 http_method: Method::GET,
38 api_path: "/open-apis/drive/explorer/v2/root_folder/meta".to_string(),
39 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
40 ..Default::default()
41 };
42
43 let api_resp = Transport::request(api_req, &self.config, option).await?;
44
45 Ok(api_resp)
46 }
47
48 pub async fn folder_meta(
52 &self,
53 folder_token: &str,
54 option: Option<RequestOption>,
55 ) -> SDKResult<BaseResponse<ExplorerFolderMeta>> {
56 let api_req = ApiRequest {
57 http_method: Method::GET,
58 api_path: format!("/open-apis/drive/explorer/v2/folder/{folder_token}/meta"),
59 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
60 ..Default::default()
61 };
62
63 let api_resp = Transport::request(api_req, &self.config, option).await?;
64
65 Ok(api_resp)
66 }
67
68 pub async fn create_folder(
71 &self,
72 create_folder_request: CreateFolderRequest,
73 option: Option<RequestOption>,
74 ) -> SDKResult<BaseResponse<CreateFolderResponse>> {
75 let mut api_req = create_folder_request.api_req;
76 api_req.http_method = Method::POST;
77 api_req.api_path = "/open-apis/drive/v1/files/create_folder".to_string();
78 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
79
80 let api_resp = Transport::request(api_req, &self.config, option).await?;
81
82 Ok(api_resp)
83 }
84
85 pub async fn list_folder(
89 &self,
90 list_folder_request: ListFolderRequest,
91 option: Option<RequestOption>,
92 ) -> SDKResult<BaseResponse<ListFolderResponse>> {
93 let mut api_req = list_folder_request.api_req;
94 api_req.http_method = Method::GET;
95 api_req.api_path = "/open-apis/drive/v1/files".to_string();
96 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
97
98 let api_resp = Transport::request(api_req, &self.config, option).await?;
99
100 Ok(api_resp)
101 }
102
103 pub fn list_folder_iter(
104 &self,
105 req: ListFolderRequest,
106 option: Option<RequestOption>,
107 ) -> ListFolderIterator<'_> {
108 ListFolderIterator {
109 explorer_service: self,
110 req,
111 option,
112 has_more: true,
113 }
114 }
115}
116
117pub struct ListFolderIterator<'a> {
118 explorer_service: &'a ExplorerService,
119 req: ListFolderRequest,
120 option: Option<RequestOption>,
121 has_more: bool,
122}
123
124impl ListFolderIterator<'_> {
125 pub async fn next(&mut self) -> Option<Vec<FileInFolder>> {
126 if !self.has_more {
127 return None;
128 }
129
130 match self
131 .explorer_service
132 .list_folder(self.req.clone(), self.option.clone())
133 .await
134 {
135 Ok(resp) => match resp.data {
136 Some(data) => {
137 self.has_more = data.has_more;
138 if data.has_more {
139 self.req
140 .api_req
141 .query_params
142 .insert("page_token".to_string(), data.next_page_token.unwrap());
143 Some(data.files)
144 } else if data.files.is_empty() {
145 None
146 } else {
147 Some(data.files)
148 }
149 }
150 None => None,
151 },
152 Err(e) => {
153 error!("Error: {e:?}");
154 None
155 }
156 }
157 }
158}
159
160#[derive(Debug, Serialize, Deserialize)]
162pub struct ExplorerRootMeta {
163 pub token: String,
165 pub id: String,
167 pub user_id: String,
169}
170
171impl ApiResponseTrait for ExplorerRootMeta {
172 fn data_format() -> ResponseFormat {
173 ResponseFormat::Data
174 }
175}
176
177#[derive(Debug, Serialize, Deserialize)]
179pub struct ExplorerFolderMeta {
180 pub id: String,
182 pub name: String,
184 pub token: String,
186 #[serde(rename = "createUid")]
188 pub create_uid: String,
189 #[serde(rename = "editUid")]
191 pub edit_uid: String,
192 #[serde(rename = "parentId")]
194 pub parent_id: String,
195 #[serde(rename = "ownUid")]
197 pub own_uid: String,
198}
199
200impl ApiResponseTrait for ExplorerFolderMeta {
201 fn data_format() -> ResponseFormat {
202 ResponseFormat::Data
203 }
204}
205
206#[derive(Default, Serialize, Deserialize)]
207pub struct CreateFolderRequest {
208 #[serde(skip)]
210 api_req: ApiRequest,
211 name: String,
215 folder_token: String,
217}
218
219impl CreateFolderRequest {
220 pub fn builder() -> CreateFolderRequestBuilder {
221 CreateFolderRequestBuilder::default()
222 }
223}
224
225#[derive(Default)]
226pub struct CreateFolderRequestBuilder {
228 request: CreateFolderRequest,
229}
230
231impl CreateFolderRequestBuilder {
232 pub fn name(mut self, name: impl ToString) -> Self {
234 self.request.name = name.to_string();
235 self
236 }
237
238 pub fn folder_token(mut self, folder_token: impl ToString) -> Self {
240 self.request.folder_token = folder_token.to_string();
241 self
242 }
243
244 pub fn build(mut self) -> CreateFolderRequest {
245 self.request.api_req.body = serde_json::to_vec(&self.request).unwrap();
246
247 self.request
248 }
249}
250
251#[derive(Debug, Serialize, Deserialize)]
253pub struct CreateFolderResponse {
254 pub token: String,
256 pub url: String,
258}
259
260impl ApiResponseTrait for CreateFolderResponse {
261 fn data_format() -> ResponseFormat {
262 ResponseFormat::Data
263 }
264}
265
266#[derive(Default)]
268pub struct ListFolderRequestBuilder {
269 request: ListFolderRequest,
270}
271
272impl ListFolderRequestBuilder {
273 pub fn page_size(mut self, page_size: i32) -> Self {
281 self.request
282 .api_req
283 .query_params
284 .insert("page_size".to_string(), page_size.to_string());
285 self
286 }
287
288 pub fn page_token(mut self, page_token: impl ToString) -> Self {
293 self.request
294 .api_req
295 .query_params
296 .insert("page_token".to_string(), page_token.to_string());
297 self
298 }
299
300 pub fn folder_token(mut self, fold_token: impl ToString) -> Self {
304 self.request
305 .api_req
306 .query_params
307 .insert("folder_token".to_string(), fold_token.to_string());
308 self
309 }
310
311 pub fn order_by(mut self, order_by: impl ToString) -> Self {
322 self.request
323 .api_req
324 .query_params
325 .insert("order_by".to_string(), order_by.to_string());
326 self
327 }
328
329 pub fn direction(mut self, direction: impl ToString) -> Self {
338 self.request
339 .api_req
340 .query_params
341 .insert("direction".to_string(), direction.to_string());
342 self
343 }
344
345 pub fn user_id_type(mut self, user_id_type: impl ToString) -> Self {
360 self.request
361 .api_req
362 .query_params
363 .insert("user_id_type".to_string(), user_id_type.to_string());
364 self
365 }
366
367 pub fn build(self) -> ListFolderRequest {
368 self.request
369 }
370}
371
372#[derive(Default, Clone, Serialize, Deserialize)]
374pub struct ListFolderRequest {
375 #[serde(skip)]
377 api_req: ApiRequest,
378}
379
380impl ListFolderRequest {
381 pub fn builder() -> ListFolderRequestBuilder {
382 ListFolderRequestBuilder::default()
383 }
384}
385
386#[derive(Debug, Serialize, Deserialize)]
387pub struct ListFolderResponse {
388 pub files: Vec<FileInFolder>,
390 #[serde(skip_serializing_if = "Option::is_none")]
392 pub next_page_token: Option<String>,
393 pub has_more: bool,
395}
396
397#[derive(Debug, Serialize, Deserialize)]
399pub struct FileInFolder {
400 pub token: String,
402 pub name: String,
404 pub r#type: String,
424 pub parent_token: String,
426 pub url: String,
428 #[serde(skip_serializing_if = "Option::is_none")]
430 pub shortcut_info: Option<ShortcutInfo>,
431 pub created_time: String,
433 pub modified_time: String,
435 pub owner_id: String,
437}
438
439#[derive(Debug, Serialize, Deserialize)]
440pub struct ShortcutInfo {
441 pub target_type: String,
457 pub target_token: String,
459}
460
461impl ApiResponseTrait for ListFolderResponse {
462 fn data_format() -> ResponseFormat {
463 ResponseFormat::Data
464 }
465}
466
467impl_executable_builder_owned!(
468 CreateFolderRequestBuilder,
469 ExplorerService,
470 CreateFolderRequest,
471 BaseResponse<CreateFolderResponse>,
472 create_folder
473);
474
475impl_executable_builder_owned!(
476 ListFolderRequestBuilder,
477 ExplorerService,
478 ListFolderRequest,
479 BaseResponse<ListFolderResponse>,
480 list_folder
481);