1use reqwest::Method;
2use serde::{Deserialize, Serialize};
3
4use crate::{
5 core::{
6 api_req::ApiRequest,
7 api_resp::{ApiResponseTrait, BaseResponse, ResponseFormat},
8 config::Config,
9 constants::AccessTokenType,
10 http::Transport,
11 req_option::RequestOption,
12 SDKResult,
13 },
14 impl_executable_builder_owned,
15};
16
17pub struct FileService {
19 config: Config,
20}
21
22impl FileService {
23 pub fn new(config: Config) -> Self {
24 Self { config }
25 }
26
27 pub async fn get_file_meta(
33 &self,
34 request: GetFileMetaRequest,
35 option: Option<RequestOption>,
36 ) -> SDKResult<BaseResponse<GetFileMetaRespData>> {
37 let api_req = ApiRequest {
38 http_method: Method::POST,
39 api_path: "/open-apis/drive/v1/metas/batch_query".to_string(),
40 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
41 body: serde_json::to_vec(&request)?,
42 ..Default::default()
43 };
44
45 let api_resp = Transport::request(api_req, &self.config, option).await?;
46 Ok(api_resp)
47 }
48
49 pub async fn get_file_statistics(
55 &self,
56 request: GetFileStatisticsRequest,
57 option: Option<RequestOption>,
58 ) -> SDKResult<BaseResponse<GetFileStatisticsRespData>> {
59 let api_req = ApiRequest {
60 http_method: Method::GET,
61 api_path: format!(
62 "/open-apis/drive/v1/files/{}/statistics",
63 request.file_token
64 ),
65 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
66 ..Default::default()
67 };
68
69 let api_resp = Transport::request(api_req, &self.config, option).await?;
70 Ok(api_resp)
71 }
72
73 pub async fn list_file_view_records(
79 &self,
80 request: ListFileViewRecordsRequest,
81 option: Option<RequestOption>,
82 ) -> SDKResult<BaseResponse<ListFileViewRecordsRespData>> {
83 let mut api_req = ApiRequest {
84 http_method: Method::GET,
85 api_path: format!(
86 "/open-apis/drive/v1/files/{}/view_records",
87 request.file_token
88 ),
89 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
90 ..Default::default()
91 };
92
93 if let Some(page_token) = request.page_token {
95 api_req
96 .query_params
97 .insert("page_token".to_string(), page_token);
98 }
99 if let Some(page_size) = request.page_size {
100 api_req
101 .query_params
102 .insert("page_size".to_string(), page_size.to_string());
103 }
104
105 let api_resp = Transport::request(api_req, &self.config, option).await?;
106 Ok(api_resp)
107 }
108
109 pub async fn create_file(
115 &self,
116 request: CreateFileRequest,
117 option: Option<RequestOption>,
118 ) -> SDKResult<BaseResponse<CreateFileRespData>> {
119 let api_req = ApiRequest {
120 http_method: Method::POST,
121 api_path: "/open-apis/drive/v1/files".to_string(),
122 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
123 body: serde_json::to_vec(&request)?,
124 ..Default::default()
125 };
126
127 let api_resp = Transport::request(api_req, &self.config, option).await?;
128 Ok(api_resp)
129 }
130
131 pub async fn copy_file(
137 &self,
138 request: CopyFileRequest,
139 option: Option<RequestOption>,
140 ) -> SDKResult<BaseResponse<CopyFileRespData>> {
141 let body = serde_json::json!({
143 "name": request.name,
144 "type": request.copy_type,
145 "parent_token": request.parent_token
146 });
147
148 let api_req = ApiRequest {
149 http_method: Method::POST,
150 api_path: format!("/open-apis/drive/v1/files/{}/copy", request.file_token),
151 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
152 body: serde_json::to_vec(&body)?,
153 ..Default::default()
154 };
155
156 let api_resp = Transport::request(api_req, &self.config, option).await?;
157 Ok(api_resp)
158 }
159
160 pub async fn delete_file(
166 &self,
167 request: DeleteFileRequest,
168 option: Option<RequestOption>,
169 ) -> SDKResult<BaseResponse<DeleteFileRespData>> {
170 let api_req = ApiRequest {
171 http_method: Method::DELETE,
172 api_path: format!("/open-apis/drive/v1/files/{}", request.file_token),
173 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
174 ..Default::default()
175 };
176
177 let api_resp = Transport::request(api_req, &self.config, option).await?;
178 Ok(api_resp)
179 }
180
181 pub async fn create_file_shortcut(
187 &self,
188 request: CreateFileShortcutRequest,
189 option: Option<RequestOption>,
190 ) -> SDKResult<BaseResponse<CreateFileShortcutRespData>> {
191 let api_req = ApiRequest {
192 http_method: Method::POST,
193 api_path: "/open-apis/drive/v1/files/create_shortcut".to_string(),
194 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
195 body: serde_json::to_vec(&request)?,
196 ..Default::default()
197 };
198
199 let api_resp = Transport::request(api_req, &self.config, option).await?;
200 Ok(api_resp)
201 }
202
203 pub async fn search_files(
209 &self,
210 request: SearchFilesRequest,
211 option: Option<RequestOption>,
212 ) -> SDKResult<BaseResponse<SearchFilesRespData>> {
213 let mut api_req = ApiRequest {
214 http_method: Method::GET,
215 api_path: "/open-apis/drive/v1/files/search".to_string(),
216 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
217 ..Default::default()
218 };
219
220 api_req
222 .query_params
223 .insert("search_key".to_string(), request.search_key);
224 if let Some(count) = request.count {
225 api_req
226 .query_params
227 .insert("count".to_string(), count.to_string());
228 }
229 if let Some(offset) = request.offset {
230 api_req
231 .query_params
232 .insert("offset".to_string(), offset.to_string());
233 }
234 if let Some(owner_ids) = request.owner_ids {
235 api_req
236 .query_params
237 .insert("owner_ids".to_string(), owner_ids.join(","));
238 }
239
240 let api_resp = Transport::request(api_req, &self.config, option).await?;
241 Ok(api_resp)
242 }
243
244 pub async fn upload_prepare(
250 &self,
251 request: FileUploadPrepareRequest,
252 option: Option<RequestOption>,
253 ) -> SDKResult<BaseResponse<FileUploadPrepareRespData>> {
254 let api_req = ApiRequest {
255 http_method: Method::POST,
256 api_path: "/open-apis/drive/v1/files/upload_prepare".to_string(),
257 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
258 body: serde_json::to_vec(&request)?,
259 ..Default::default()
260 };
261
262 let api_resp = Transport::request(api_req, &self.config, option).await?;
263 Ok(api_resp)
264 }
265
266 pub async fn upload_part(
272 &self,
273 request: FileUploadPartRequest,
274 option: Option<RequestOption>,
275 ) -> SDKResult<BaseResponse<FileUploadPartRespData>> {
276 let mut api_req = request.api_req;
277 api_req.http_method = Method::POST;
278 api_req.api_path = "/open-apis/drive/v1/files/upload_part".to_string();
279 api_req.supported_access_token_types = vec![AccessTokenType::User, AccessTokenType::Tenant];
280
281 let api_resp = Transport::request(api_req, &self.config, option).await?;
282 Ok(api_resp)
283 }
284
285 pub async fn upload_finish(
291 &self,
292 request: FileUploadFinishRequest,
293 option: Option<RequestOption>,
294 ) -> SDKResult<BaseResponse<FileUploadFinishRespData>> {
295 let api_req = ApiRequest {
296 http_method: Method::POST,
297 api_path: "/open-apis/drive/v1/files/upload_finish".to_string(),
298 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
299 body: serde_json::to_vec(&request)?,
300 ..Default::default()
301 };
302
303 let api_resp = Transport::request(api_req, &self.config, option).await?;
304 Ok(api_resp)
305 }
306
307 pub async fn create_import_task(
313 &self,
314 request: CreateImportTaskRequest,
315 option: Option<RequestOption>,
316 ) -> SDKResult<BaseResponse<CreateImportTaskRespData>> {
317 let api_req = ApiRequest {
318 http_method: Method::POST,
319 api_path: "/open-apis/drive/v1/import_tasks".to_string(),
320 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
321 body: serde_json::to_vec(&request)?,
322 ..Default::default()
323 };
324
325 let api_resp = Transport::request(api_req, &self.config, option).await?;
326 Ok(api_resp)
327 }
328
329 pub async fn get_import_task(
335 &self,
336 request: GetImportTaskRequest,
337 option: Option<RequestOption>,
338 ) -> SDKResult<BaseResponse<GetImportTaskRespData>> {
339 let api_req = ApiRequest {
340 http_method: Method::GET,
341 api_path: format!("/open-apis/drive/v1/import_tasks/{}", request.ticket),
342 supported_access_token_types: vec![AccessTokenType::User, AccessTokenType::Tenant],
343 ..Default::default()
344 };
345
346 let api_resp = Transport::request(api_req, &self.config, option).await?;
347 Ok(api_resp)
348 }
349}
350
351#[derive(Debug, Clone, Serialize, Deserialize)]
355pub struct GetFileMetaRequest {
356 pub request_docs: Vec<RequestDoc>,
358 pub with_url: Option<bool>,
360}
361
362#[derive(Debug, Clone, Serialize, Deserialize)]
363pub struct RequestDoc {
364 pub doc_token: String,
366 pub doc_type: String,
368}
369
370impl GetFileMetaRequest {
371 pub fn new(docs: Vec<(String, String)>) -> Self {
372 Self {
373 request_docs: docs
374 .into_iter()
375 .map(|(token, doc_type)| RequestDoc {
376 doc_token: token,
377 doc_type,
378 })
379 .collect(),
380 with_url: Some(true),
381 }
382 }
383}
384
385#[derive(Debug, Clone, Serialize, Deserialize)]
387pub struct GetFileMetaRespData {
388 pub metas: Vec<FileMeta>,
390}
391
392#[derive(Debug, Clone, Serialize, Deserialize)]
393pub struct FileMeta {
394 pub doc_token: String,
396 pub doc_type: String,
398 pub title: String,
400 pub owner_id: String,
402 pub create_time: String,
404 pub update_time: String,
406 pub url: Option<String>,
408}
409
410impl ApiResponseTrait for GetFileMetaRespData {
411 fn data_format() -> ResponseFormat {
412 ResponseFormat::Data
413 }
414}
415
416#[derive(Debug, Clone, Serialize, Deserialize)]
418pub struct GetFileStatisticsRequest {
419 pub file_token: String,
421}
422
423impl GetFileStatisticsRequest {
424 pub fn new(file_token: impl Into<String>) -> Self {
425 Self {
426 file_token: file_token.into(),
427 }
428 }
429}
430
431#[derive(Debug, Clone, Serialize, Deserialize)]
433pub struct GetFileStatisticsRespData {
434 pub uv: i64,
436 pub pv: i64,
438 pub like_count: i64,
440 pub comment_count: i64,
442}
443
444impl ApiResponseTrait for GetFileStatisticsRespData {
445 fn data_format() -> ResponseFormat {
446 ResponseFormat::Data
447 }
448}
449
450#[derive(Debug, Clone, Serialize, Deserialize)]
452pub struct ListFileViewRecordsRequest {
453 pub file_token: String,
455 pub page_token: Option<String>,
457 pub page_size: Option<i32>,
459}
460
461impl ListFileViewRecordsRequest {
462 pub fn new(file_token: impl Into<String>) -> Self {
463 Self {
464 file_token: file_token.into(),
465 page_token: None,
466 page_size: None,
467 }
468 }
469
470 pub fn with_page_token(mut self, page_token: impl Into<String>) -> Self {
471 self.page_token = Some(page_token.into());
472 self
473 }
474
475 pub fn with_page_size(mut self, page_size: i32) -> Self {
476 self.page_size = Some(page_size);
477 self
478 }
479}
480
481#[derive(Debug, Clone, Serialize, Deserialize)]
483pub struct ListFileViewRecordsRespData {
484 pub has_more: bool,
486 pub page_token: Option<String>,
488 pub items: Vec<FileViewRecord>,
490}
491
492#[derive(Debug, Clone, Serialize, Deserialize)]
493pub struct FileViewRecord {
494 pub viewer_id: String,
496 pub viewer_name: String,
498 pub view_time: String,
500 pub view_device: String,
502}
503
504impl ApiResponseTrait for ListFileViewRecordsRespData {
505 fn data_format() -> ResponseFormat {
506 ResponseFormat::Data
507 }
508}
509
510#[derive(Debug, Clone, Serialize, Deserialize)]
512pub struct CreateFileRequest {
513 pub title: String,
515 #[serde(rename = "type")]
517 pub file_type: String,
518 pub parent_token: String,
520}
521
522impl CreateFileRequest {
523 pub fn new(
524 title: impl Into<String>,
525 file_type: impl Into<String>,
526 parent_token: impl Into<String>,
527 ) -> Self {
528 Self {
529 title: title.into(),
530 file_type: file_type.into(),
531 parent_token: parent_token.into(),
532 }
533 }
534}
535
536#[derive(Debug, Clone, Serialize, Deserialize)]
538pub struct CreateFileRespData {
539 pub token: String,
541 pub url: String,
543}
544
545impl ApiResponseTrait for CreateFileRespData {
546 fn data_format() -> ResponseFormat {
547 ResponseFormat::Data
548 }
549}
550
551#[derive(Debug, Clone, Serialize, Deserialize)]
553pub struct CopyFileRequest {
554 pub file_token: String,
556 pub name: String,
558 #[serde(rename = "type")]
560 pub copy_type: String,
561 pub parent_token: String,
563}
564
565impl CopyFileRequest {
566 pub fn new(
567 file_token: impl Into<String>,
568 name: impl Into<String>,
569 parent_token: impl Into<String>,
570 ) -> Self {
571 Self {
572 file_token: file_token.into(),
573 name: name.into(),
574 copy_type: "copy".to_string(),
575 parent_token: parent_token.into(),
576 }
577 }
578}
579
580#[derive(Debug, Clone, Serialize, Deserialize)]
582pub struct CopyFileRespData {
583 pub token: String,
585 pub url: String,
587}
588
589impl ApiResponseTrait for CopyFileRespData {
590 fn data_format() -> ResponseFormat {
591 ResponseFormat::Data
592 }
593}
594
595#[derive(Debug, Clone, Serialize, Deserialize)]
597pub struct DeleteFileRequest {
598 pub file_token: String,
600}
601
602impl DeleteFileRequest {
603 pub fn new(file_token: impl Into<String>) -> Self {
604 Self {
605 file_token: file_token.into(),
606 }
607 }
608}
609
610#[derive(Debug, Clone, Serialize, Deserialize)]
612pub struct DeleteFileRespData {
613 pub task_id: Option<String>,
615}
616
617impl ApiResponseTrait for DeleteFileRespData {
618 fn data_format() -> ResponseFormat {
619 ResponseFormat::Data
620 }
621}
622
623#[derive(Debug, Clone, Serialize, Deserialize)]
625pub struct CreateFileShortcutRequest {
626 pub refer_entity: ReferEntity,
628 pub name: String,
630 pub parent_token: String,
632}
633
634#[derive(Debug, Clone, Serialize, Deserialize)]
635pub struct ReferEntity {
636 #[serde(rename = "type")]
638 pub entity_type: String,
639 pub token: String,
641}
642
643impl CreateFileShortcutRequest {
644 pub fn new(
645 file_type: impl Into<String>,
646 file_token: impl Into<String>,
647 name: impl Into<String>,
648 parent_token: impl Into<String>,
649 ) -> Self {
650 Self {
651 refer_entity: ReferEntity {
652 entity_type: file_type.into(),
653 token: file_token.into(),
654 },
655 name: name.into(),
656 parent_token: parent_token.into(),
657 }
658 }
659}
660
661#[derive(Debug, Clone, Serialize, Deserialize)]
663pub struct CreateFileShortcutRespData {
664 pub token: String,
666 pub url: String,
668}
669
670impl ApiResponseTrait for CreateFileShortcutRespData {
671 fn data_format() -> ResponseFormat {
672 ResponseFormat::Data
673 }
674}
675
676#[derive(Debug, Clone, Serialize, Deserialize)]
678pub struct SearchFilesRequest {
679 pub search_key: String,
681 pub count: Option<i32>,
683 pub offset: Option<i32>,
685 pub owner_ids: Option<Vec<String>>,
687}
688
689impl SearchFilesRequest {
690 pub fn new(search_key: impl Into<String>) -> Self {
691 Self {
692 search_key: search_key.into(),
693 count: None,
694 offset: None,
695 owner_ids: None,
696 }
697 }
698
699 pub fn with_count(mut self, count: i32) -> Self {
700 self.count = Some(count);
701 self
702 }
703
704 pub fn with_offset(mut self, offset: i32) -> Self {
705 self.offset = Some(offset);
706 self
707 }
708
709 pub fn with_owner_ids(mut self, owner_ids: Vec<String>) -> Self {
710 self.owner_ids = Some(owner_ids);
711 self
712 }
713}
714
715#[derive(Debug, Clone, Serialize, Deserialize)]
717pub struct SearchFilesRespData {
718 pub files: Vec<SearchFileItem>,
720}
721
722#[derive(Debug, Clone, Serialize, Deserialize)]
723pub struct SearchFileItem {
724 pub token: String,
726 pub name: String,
728 #[serde(rename = "type")]
730 pub file_type: String,
731 pub url: String,
733 pub owner_id: String,
735}
736
737impl ApiResponseTrait for SearchFilesRespData {
738 fn data_format() -> ResponseFormat {
739 ResponseFormat::Data
740 }
741}
742
743#[derive(Debug, Clone, Serialize, Deserialize)]
745pub struct FileUploadPrepareRequest {
746 pub file_name: String,
748 pub parent_token: String,
750 pub size: i64,
752 pub block_size: Option<i32>,
754 pub checksum: Option<String>,
756}
757
758impl FileUploadPrepareRequest {
759 pub fn new(file_name: impl Into<String>, parent_token: impl Into<String>, size: i64) -> Self {
760 Self {
761 file_name: file_name.into(),
762 parent_token: parent_token.into(),
763 size,
764 block_size: None,
765 checksum: None,
766 }
767 }
768
769 pub fn with_block_size(mut self, block_size: i32) -> Self {
770 self.block_size = Some(block_size);
771 self
772 }
773
774 pub fn with_checksum(mut self, checksum: impl Into<String>) -> Self {
775 self.checksum = Some(checksum.into());
776 self
777 }
778}
779
780#[derive(Debug, Clone, Serialize, Deserialize)]
782pub struct FileUploadPrepareRespData {
783 pub upload_id: String,
785 pub block_size: i32,
787 pub block_num: i32,
789}
790
791impl ApiResponseTrait for FileUploadPrepareRespData {
792 fn data_format() -> ResponseFormat {
793 ResponseFormat::Data
794 }
795}
796
797#[derive(Debug, Clone, Default, Serialize, Deserialize)]
799pub struct FileUploadPartRequest {
800 #[serde(skip)]
802 pub api_req: ApiRequest,
803 upload_id: String,
805 seq: i32,
807 size: i32,
809 checksum: Option<String>,
811}
812
813impl FileUploadPartRequest {
814 pub fn builder() -> FileUploadPartRequestBuilder {
815 FileUploadPartRequestBuilder::default()
816 }
817}
818
819#[derive(Default)]
821pub struct FileUploadPartRequestBuilder {
822 request: FileUploadPartRequest,
823}
824
825impl FileUploadPartRequestBuilder {
826 pub fn upload_id(mut self, upload_id: impl Into<String>) -> Self {
827 self.request.upload_id = upload_id.into();
828 self
829 }
830
831 pub fn seq(mut self, seq: i32) -> Self {
832 self.request.seq = seq;
833 self
834 }
835
836 pub fn size(mut self, size: i32) -> Self {
837 self.request.size = size;
838 self
839 }
840
841 pub fn checksum(mut self, checksum: impl Into<String>) -> Self {
842 self.request.checksum = Some(checksum.into());
843 self
844 }
845
846 pub fn file_chunk(mut self, chunk: Vec<u8>) -> Self {
847 self.request.api_req.file = chunk;
848 self
849 }
850
851 pub fn build(mut self) -> FileUploadPartRequest {
852 self.request.api_req.body = serde_json::to_vec(&self.request).unwrap();
853 self.request
854 }
855}
856
857impl_executable_builder_owned!(
858 FileUploadPartRequestBuilder,
859 FileService,
860 FileUploadPartRequest,
861 BaseResponse<FileUploadPartRespData>,
862 upload_part
863);
864
865#[derive(Debug, Clone, Serialize, Deserialize)]
867pub struct FileUploadPartRespData {
868 pub etag: String,
870}
871
872impl ApiResponseTrait for FileUploadPartRespData {
873 fn data_format() -> ResponseFormat {
874 ResponseFormat::Data
875 }
876}
877
878#[derive(Debug, Clone, Serialize, Deserialize)]
880pub struct FileUploadFinishRequest {
881 pub upload_id: String,
883 pub block_infos: Vec<FileBlockInfo>,
885}
886
887#[derive(Debug, Clone, Serialize, Deserialize)]
888pub struct FileBlockInfo {
889 pub etag: String,
891 pub seq: i32,
893}
894
895impl FileUploadFinishRequest {
896 pub fn new(upload_id: impl Into<String>, block_infos: Vec<FileBlockInfo>) -> Self {
897 Self {
898 upload_id: upload_id.into(),
899 block_infos,
900 }
901 }
902}
903
904#[derive(Debug, Clone, Serialize, Deserialize)]
906pub struct FileUploadFinishRespData {
907 pub file_token: String,
909}
910
911impl ApiResponseTrait for FileUploadFinishRespData {
912 fn data_format() -> ResponseFormat {
913 ResponseFormat::Data
914 }
915}
916
917#[derive(Debug, Clone, Serialize, Deserialize)]
919pub struct CreateImportTaskRequest {
920 pub file_extension: String,
922 pub file_token: String,
924 #[serde(rename = "type")]
926 pub import_type: String,
927 pub parent_token: String,
929 pub file_name: String,
931 pub parent_type: String,
933}
934
935impl CreateImportTaskRequest {
936 pub fn new(
937 file_extension: impl Into<String>,
938 file_token: impl Into<String>,
939 import_type: impl Into<String>,
940 parent_token: impl Into<String>,
941 file_name: impl Into<String>,
942 parent_type: impl Into<String>,
943 ) -> Self {
944 Self {
945 file_extension: file_extension.into(),
946 file_token: file_token.into(),
947 import_type: import_type.into(),
948 parent_token: parent_token.into(),
949 file_name: file_name.into(),
950 parent_type: parent_type.into(),
951 }
952 }
953}
954
955#[derive(Debug, Clone, Serialize, Deserialize)]
957pub struct CreateImportTaskRespData {
958 pub ticket: String,
960}
961
962impl ApiResponseTrait for CreateImportTaskRespData {
963 fn data_format() -> ResponseFormat {
964 ResponseFormat::Data
965 }
966}
967
968#[derive(Debug, Clone, Serialize, Deserialize)]
970pub struct GetImportTaskRequest {
971 pub ticket: String,
973}
974
975impl GetImportTaskRequest {
976 pub fn new(ticket: impl Into<String>) -> Self {
977 Self {
978 ticket: ticket.into(),
979 }
980 }
981}
982
983#[derive(Debug, Clone, Serialize, Deserialize)]
985pub struct GetImportTaskRespData {
986 pub result: ImportTaskResult,
988}
989
990#[derive(Debug, Clone, Serialize, Deserialize)]
991pub struct ImportTaskResult {
992 #[serde(rename = "type")]
994 pub task_type: String,
995 pub ticket: String,
997 pub job_status: i32,
999 pub job_error_msg: Option<String>,
1001 pub token: Option<String>,
1003 pub url: Option<String>,
1005}
1006
1007impl ApiResponseTrait for GetImportTaskRespData {
1008 fn data_format() -> ResponseFormat {
1009 ResponseFormat::Data
1010 }
1011}