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 endpoints::cloud_docs::*,
14 http::Transport,
15 req_option::RequestOption,
16 SDKResult,
17 },
18 impl_executable_builder_owned,
19};
20
21pub struct ExplorerService {
22 config: Config,
23}
24
25impl ExplorerService {
26 pub fn new(config: Config) -> Self {
27 Self { config }
28 }
29
30 pub async fn root_folder_meta(
34 &self,
35 option: Option<RequestOption>,
36 ) -> SDKResult<BaseResponse<ExplorerRootMeta>> {
37 let api_req = ApiRequest {
38 http_method: Method::GET,
39 api_path: DRIVE_EXPLORER_V2_ROOT_FOLDER_META.to_string(),
40 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
41 ..Default::default()
42 };
43
44 let api_resp = Transport::request(api_req, &self.config, option).await?;
45
46 Ok(api_resp)
47 }
48
49 pub async fn folder_meta(
53 &self,
54 folder_token: &str,
55 option: Option<RequestOption>,
56 ) -> SDKResult<BaseResponse<ExplorerFolderMeta>> {
57 let api_req = ApiRequest {
58 http_method: Method::GET,
59 api_path: DRIVE_EXPLORER_V2_FOLDER_META.replace("{folder_token}", folder_token),
60 supported_access_token_types: vec![AccessTokenType::Tenant, AccessTokenType::User],
61 ..Default::default()
62 };
63
64 let api_resp = Transport::request(api_req, &self.config, option).await?;
65
66 Ok(api_resp)
67 }
68
69 pub async fn create_folder(
72 &self,
73 create_folder_request: CreateFolderRequest,
74 option: Option<RequestOption>,
75 ) -> SDKResult<BaseResponse<CreateFolderResponse>> {
76 let mut api_req = create_folder_request.api_req;
77 api_req.http_method = Method::POST;
78 api_req.api_path = DRIVE_V1_FILES_CREATE_FOLDER.to_string();
79 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
80
81 let api_resp = Transport::request(api_req, &self.config, option).await?;
82
83 Ok(api_resp)
84 }
85
86 pub async fn list_folder(
90 &self,
91 list_folder_request: ListFolderRequest,
92 option: Option<RequestOption>,
93 ) -> SDKResult<BaseResponse<ListFolderResponse>> {
94 let mut api_req = list_folder_request.api_req;
95 api_req.http_method = Method::GET;
96 api_req.api_path = DRIVE_V1_FILES.to_string();
97 api_req.supported_access_token_types = vec![AccessTokenType::Tenant, AccessTokenType::User];
98
99 let api_resp = Transport::request(api_req, &self.config, option).await?;
100
101 Ok(api_resp)
102 }
103
104 pub fn list_folder_iter(
105 &self,
106 req: ListFolderRequest,
107 option: Option<RequestOption>,
108 ) -> ListFolderIterator<'_> {
109 ListFolderIterator {
110 explorer_service: self,
111 req,
112 option,
113 has_more: true,
114 }
115 }
116}
117
118pub struct ListFolderIterator<'a> {
119 explorer_service: &'a ExplorerService,
120 req: ListFolderRequest,
121 option: Option<RequestOption>,
122 has_more: bool,
123}
124
125impl ListFolderIterator<'_> {
126 pub async fn next(&mut self) -> Option<Vec<FileInFolder>> {
127 if !self.has_more {
128 return None;
129 }
130
131 match self
132 .explorer_service
133 .list_folder(self.req.clone(), self.option.clone())
134 .await
135 {
136 Ok(resp) => match resp.data {
137 Some(data) => {
138 self.has_more = data.has_more;
139 if data.has_more {
140 self.req
141 .api_req
142 .query_params
143 .insert("page_token", data.next_page_token.unwrap());
144 Some(data.files)
145 } else if data.files.is_empty() {
146 None
147 } else {
148 Some(data.files)
149 }
150 }
151 None => None,
152 },
153 Err(e) => {
154 error!("Error: {e:?}");
155 None
156 }
157 }
158 }
159}
160
161#[derive(Debug, Serialize, Deserialize)]
163pub struct ExplorerRootMeta {
164 pub token: String,
166 pub id: String,
168 pub user_id: String,
170}
171
172impl ApiResponseTrait for ExplorerRootMeta {
173 fn data_format() -> ResponseFormat {
174 ResponseFormat::Data
175 }
176}
177
178#[derive(Debug, Serialize, Deserialize)]
180pub struct ExplorerFolderMeta {
181 pub id: String,
183 pub name: String,
185 pub token: String,
187 #[serde(rename = "createUid")]
189 pub create_uid: String,
190 #[serde(rename = "editUid")]
192 pub edit_uid: String,
193 #[serde(rename = "parentId")]
195 pub parent_id: String,
196 #[serde(rename = "ownUid")]
198 pub own_uid: String,
199}
200
201impl ApiResponseTrait for ExplorerFolderMeta {
202 fn data_format() -> ResponseFormat {
203 ResponseFormat::Data
204 }
205}
206
207#[derive(Default, Serialize, Deserialize)]
208pub struct CreateFolderRequest {
209 #[serde(skip)]
211 api_req: ApiRequest,
212 name: String,
216 folder_token: String,
218}
219
220impl CreateFolderRequest {
221 pub fn builder() -> CreateFolderRequestBuilder {
222 CreateFolderRequestBuilder::default()
223 }
224}
225
226#[derive(Default)]
227pub struct CreateFolderRequestBuilder {
229 request: CreateFolderRequest,
230}
231
232impl CreateFolderRequestBuilder {
233 pub fn name(mut self, name: impl ToString) -> Self {
235 self.request.name = name.to_string();
236 self
237 }
238
239 pub fn folder_token(mut self, folder_token: impl ToString) -> Self {
241 self.request.folder_token = folder_token.to_string();
242 self
243 }
244
245 pub fn build(mut self) -> CreateFolderRequest {
246 self.request.api_req.body = serde_json::to_vec(&self.request).unwrap();
247
248 self.request
249 }
250}
251
252#[derive(Debug, Serialize, Deserialize)]
254pub struct CreateFolderResponse {
255 pub token: String,
257 pub url: String,
259}
260
261impl ApiResponseTrait for CreateFolderResponse {
262 fn data_format() -> ResponseFormat {
263 ResponseFormat::Data
264 }
265}
266
267#[derive(Default)]
269pub struct ListFolderRequestBuilder {
270 request: ListFolderRequest,
271}
272
273impl ListFolderRequestBuilder {
274 pub fn page_size(mut self, page_size: i32) -> Self {
282 self.request
283 .api_req
284 .query_params
285 .insert("page_size", page_size.to_string());
286 self
287 }
288
289 pub fn page_token(mut self, page_token: impl ToString) -> Self {
294 self.request
295 .api_req
296 .query_params
297 .insert("page_token", page_token.to_string());
298 self
299 }
300
301 pub fn folder_token(mut self, fold_token: impl ToString) -> Self {
305 self.request
306 .api_req
307 .query_params
308 .insert("folder_token", fold_token.to_string());
309 self
310 }
311
312 pub fn order_by(mut self, order_by: impl ToString) -> Self {
323 self.request
324 .api_req
325 .query_params
326 .insert("order_by", order_by.to_string());
327 self
328 }
329
330 pub fn direction(mut self, direction: impl ToString) -> Self {
339 self.request
340 .api_req
341 .query_params
342 .insert("direction", direction.to_string());
343 self
344 }
345
346 pub fn user_id_type(mut self, user_id_type: impl ToString) -> Self {
361 self.request
362 .api_req
363 .query_params
364 .insert("user_id_type", user_id_type.to_string());
365 self
366 }
367
368 pub fn build(self) -> ListFolderRequest {
369 self.request
370 }
371}
372
373#[derive(Default, Clone, Serialize, Deserialize)]
375pub struct ListFolderRequest {
376 #[serde(skip)]
378 api_req: ApiRequest,
379}
380
381impl ListFolderRequest {
382 pub fn builder() -> ListFolderRequestBuilder {
383 ListFolderRequestBuilder::default()
384 }
385}
386
387#[derive(Debug, Serialize, Deserialize)]
388pub struct ListFolderResponse {
389 pub files: Vec<FileInFolder>,
391 #[serde(skip_serializing_if = "Option::is_none")]
393 pub next_page_token: Option<String>,
394 pub has_more: bool,
396}
397
398#[derive(Debug, Serialize, Deserialize)]
400pub struct FileInFolder {
401 pub token: String,
403 pub name: String,
405 pub r#type: String,
425 pub parent_token: String,
427 pub url: String,
429 #[serde(skip_serializing_if = "Option::is_none")]
431 pub shortcut_info: Option<ShortcutInfo>,
432 pub created_time: String,
434 pub modified_time: String,
436 pub owner_id: String,
438}
439
440#[derive(Debug, Serialize, Deserialize)]
441pub struct ShortcutInfo {
442 pub target_type: String,
458 pub target_token: String,
460}
461
462impl ApiResponseTrait for ListFolderResponse {
463 fn data_format() -> ResponseFormat {
464 ResponseFormat::Data
465 }
466}
467
468impl_executable_builder_owned!(
469 CreateFolderRequestBuilder,
470 ExplorerService,
471 CreateFolderRequest,
472 BaseResponse<CreateFolderResponse>,
473 create_folder
474);
475
476impl_executable_builder_owned!(
477 ListFolderRequestBuilder,
478 ExplorerService,
479 ListFolderRequest,
480 BaseResponse<ListFolderResponse>,
481 list_folder
482);