1use crate::Error;
4use crate::api::v4::ApiV4Client;
5use crate::api::v4::models::*;
6use crate::api::v4::uri::*;
7
8impl ApiV4Client {
10 pub async fn upload_file(&self, request: &UploadRequest<'_>) -> Result<File, Error> {
11 let response: ApiResponse<File> = self.post("/file", request).await?;
12 match response.data {
13 Some(data) => Ok(data),
14 None => Err(Error::InvalidResponse(format!(
15 "API returned no data for upload_file request: {:?}",
16 response
17 ))),
18 }
19 }
20
21 pub async fn list_files(&self, request: &ListFilesRequest<'_>) -> Result<ListResponse, Error> {
33 let mut url = "/file".to_string();
34 if let Some(path) = request.path.strip_prefix('/') {
35 url.push_str(&format!("?uri={}", path_to_uri(path)));
36 } else {
37 url.push_str(&format!("?uri={}", path_to_uri(request.path)));
38 }
39 if let Some(page) = request.page {
40 url.push_str(&format!("&page={}", page));
41 }
42 if let Some(page_size) = request.page_size {
43 url.push_str(&format!("&page_size={}", page_size));
44 }
45 if let Some(order_by) = request.order_by {
46 url.push_str(&format!("&order_by={}", order_by));
47 }
48 if let Some(order_direction) = request.order_direction {
49 url.push_str(&format!("&order_direction={}", order_direction));
50 }
51 if let Some(next_page_token) = request.next_page_token {
52 url.push_str(&format!("&next_page_token={}", next_page_token));
53 }
54
55 let response: ApiResponse<ListResponse> = self.get(&url).await?;
56 match response.data {
57 Some(data) => Ok(data),
58 None => Err(Error::InvalidResponse(format!(
59 "API returned no data for list_files request: {:?}",
60 response
61 ))),
62 }
63 }
64
65 pub async fn get_file_info(&self, file_path: &str) -> Result<File, Error> {
66 let uri = path_to_uri(file_path);
68 let response: ApiResponse<File> = self.get(&format!("/file/info?uri={}", uri)).await?;
69 match response.data {
70 Some(data) => Ok(data),
71 None => Err(Error::InvalidResponse(format!(
72 "API returned no data for get_file_info request: {:?}",
73 response
74 ))),
75 }
76 }
77
78 pub async fn get_file_stat(&self, file_path: &str) -> Result<FileStat, Error> {
79 let response: ApiResponse<FileStat> =
80 self.get(&format!("/file/stat/{}", file_path)).await?;
81 match response.data {
82 Some(data) => Ok(data),
83 None => Err(Error::InvalidResponse(format!(
84 "API returned no data for get_file_stat request: {:?}",
85 response
86 ))),
87 }
88 }
89
90 pub async fn move_file(&self, request: &MoveFileRequest<'_>) -> Result<(), Error> {
91 let response: ApiResponse<()> = self.post("/file/move", request).await?;
92 match response.code {
93 0 => Ok(()),
94 code => Err(Error::Api {
95 code,
96 message: response.msg,
97 }),
98 }
99 }
100
101 pub async fn copy_file(&self, request: &CopyFileRequest<'_>) -> Result<(), Error> {
102 let move_request = MoveFileRequest {
104 uris: request.uris.clone(),
105 dst: request.dst,
106 copy: Some(true),
107 };
108 let response: ApiResponse<()> = self.post("/file/move", &move_request).await?;
109 match response.code {
110 0 => Ok(()),
111 code => Err(Error::Api {
112 code,
113 message: response.msg,
114 }),
115 }
116 }
117
118 pub async fn rename_file(
119 &self,
120 request: &RenameFileRequest<'_>,
121 ) -> Result<crate::api::v4::models::File, Error> {
122 let response: ApiResponse<crate::api::v4::models::File> =
123 self.post("/file/rename", request).await?;
124 match response.data {
125 Some(data) => Ok(data),
126 None => Err(Error::InvalidResponse(format!(
127 "API returned no data for rename_file request: {:?}",
128 response
129 ))),
130 }
131 }
132
133 pub async fn delete_file(&self, file_path: &str) -> Result<(), Error> {
134 let uri = path_to_uri(file_path);
136 let request = DeleteFileRequest {
137 uris: vec![uri.as_str()],
138 unlink: None,
139 skip_soft_delete: None,
140 };
141 let response: ApiResponse<()> = self.delete_with_body("/file", &request).await?;
142 match response.code {
143 0 => Ok(()),
144 code => Err(Error::Api {
145 code,
146 message: response.msg,
147 }),
148 }
149 }
150
151 pub async fn create_directory(&self, path: &str) -> Result<(), Error> {
152 let uri = path_to_uri(path);
154
155 let request = serde_json::json!({
157 "uri": uri,
158 "type": "folder"
159 });
160
161 let response: ApiResponse<serde_json::Value> = self.post("/file/create", &request).await?;
162 match response.code {
163 0 => Ok(()),
164 code => Err(Error::Api {
165 code,
166 message: response.msg,
167 }),
168 }
169 }
170
171 pub async fn set_file_permission(
172 &self,
173 request: &SetFilePermissionRequest<'_>,
174 ) -> Result<(), Error> {
175 let response: ApiResponse<()> = self.post("/file/permission", request).await?;
176 match response.code {
177 0 => Ok(()),
178 code => Err(Error::Api {
179 code,
180 message: response.msg,
181 }),
182 }
183 }
184
185 pub async fn delete_file_permission(&self, path: &str) -> Result<(), Error> {
186 let uri = path_to_uri(path);
187 let response: ApiResponse<()> = self
188 .delete(&format!("/file/permission?uri={}", uri))
189 .await?;
190 match response.code {
191 0 => Ok(()),
192 code => Err(Error::Api {
193 code,
194 message: response.msg,
195 }),
196 }
197 }
198
199 pub async fn create_upload_session(
200 &self,
201 request: &CreateUploadSessionRequest<'_>,
202 ) -> Result<UploadSessionResponse, Error> {
203 let response: ApiResponse<UploadSessionResponse> =
204 self.put("/file/upload", request).await?;
205 match response.data {
206 Some(data) => Ok(data),
207 None => Err(Error::InvalidResponse(format!(
208 "API returned no data for create_upload_session request: {:?}",
209 response
210 ))),
211 }
212 }
213
214 pub async fn upload_file_chunk(
215 &self,
216 session_id: &str,
217 index: u32,
218 chunk_data: &[u8],
219 ) -> Result<(), Error> {
220 let url = format!("/file/upload/{}/{}", session_id, index);
221 let full_url = self.get_url(&url);
222
223 let mut request = self.http_client.post(&full_url).body(chunk_data.to_vec());
224
225 if let Some(token) = &self.token {
226 request = request.bearer_auth(token);
227 }
228
229 let response = request.send().await?;
230 let status = response.status();
231
232 if !status.is_success() {
233 let error_text = response
234 .text()
235 .await
236 .unwrap_or_else(|_| "Unknown error".to_string());
237 return Err(Error::Api {
238 code: status.as_u16() as i32,
239 message: error_text,
240 });
241 }
242
243 Ok(())
244 }
245
246 pub async fn delete_upload_session(&self, path: &str, session_id: &str) -> Result<(), Error> {
247 let uri = path_to_uri(path);
248 let request = DeleteUploadSessionRequest {
249 id: session_id,
250 uri: &uri,
251 };
252 let url = self.get_url("/file/upload");
253
254 let body = serde_json::to_string(&request)?;
255
256 let mut http_req = self.http_client.delete(&url);
257 if let Some(token) = &self.token {
258 http_req = http_req.bearer_auth(token);
259 }
260
261 let response = http_req
262 .header("Content-Type", "application/json")
263 .body(body)
264 .send()
265 .await?;
266
267 let status = response.status();
268 if !status.is_success() {
269 let error_text = response
270 .text()
271 .await
272 .unwrap_or_else(|_| "Unknown error".to_string());
273 return Err(Error::Api {
274 code: status.as_u16() as i32,
275 message: error_text,
276 });
277 }
278
279 Ok(())
280 }
281
282 pub async fn get_thumbnail_url(
283 &self,
284 path: &str,
285 width: Option<u32>,
286 height: Option<u32>,
287 ) -> Result<String, Error> {
288 let uri = path_to_uri(path);
289 let mut url = format!("/file/thumb?uri={}", uri);
290 if let Some(w) = width {
291 url.push_str(&format!("&width={}", w));
292 }
293 if let Some(h) = height {
294 url.push_str(&format!("&height={}", h));
295 }
296
297 let response: ApiResponse<String> = self.get(&url).await?;
298 match response.data {
299 Some(data) => Ok(data),
300 None => Err(Error::InvalidResponse(format!(
301 "API returned no data for get_thumbnail_url request: {:?}",
302 response
303 ))),
304 }
305 }
306
307 pub async fn get_file_content(&self, path: &str) -> Result<String, Error> {
308 let uri = path_to_uri(path);
309 let response: ApiResponse<String> = self.get(&format!("/file/content?uri={}", uri)).await?;
310 match response.data {
311 Some(data) => Ok(data),
312 None => Err(Error::InvalidResponse(format!(
313 "API returned no data for get_file_content request: {:?}",
314 response
315 ))),
316 }
317 }
318
319 pub async fn update_file_content(
320 &self,
321 request: &UpdateFileContentRequest<'_>,
322 ) -> Result<(), Error> {
323 let response: ApiResponse<()> = self.put("/file/content", request).await?;
324 match response.code {
325 0 => Ok(()),
326 code => Err(Error::Api {
327 code,
328 message: response.msg,
329 }),
330 }
331 }
332
333 pub async fn create_viewer_session(
334 &self,
335 request: &CreateViewerSessionRequest<'_>,
336 ) -> Result<ViewerSessionResponse, Error> {
337 let response: ApiResponse<ViewerSessionResponse> =
338 self.put("/file/viewerSession", request).await?;
339 match response.data {
340 Some(data) => Ok(data),
341 None => Err(Error::InvalidResponse(format!(
342 "API returned no data for create_viewer_session request: {:?}",
343 response
344 ))),
345 }
346 }
347
348 pub async fn create_file(&self, request: &CreateFileRequest<'_>) -> Result<File, Error> {
349 let response: ApiResponse<File> = self.post("/file/create", request).await?;
350 match response.data {
351 Some(data) => Ok(data),
352 None => Err(Error::InvalidResponse(format!(
353 "API returned no data for create_file request: {:?}",
354 response
355 ))),
356 }
357 }
358
359 pub async fn rename_multiple(&self, request: &RenameMultipleRequest<'_>) -> Result<(), Error> {
360 let response: ApiResponse<()> = self.post("/file/rename", request).await?;
361 match response.code {
362 0 => Ok(()),
363 code => Err(Error::Api {
364 code,
365 message: response.msg,
366 }),
367 }
368 }
369
370 pub async fn move_copy_files(&self, request: &MoveCopyFileRequest<'_>) -> Result<(), Error> {
371 let response: ApiResponse<()> = self.post("/file/move", request).await?;
372 match response.code {
373 0 => Ok(()),
374 code => Err(Error::Api {
375 code,
376 message: response.msg,
377 }),
378 }
379 }
380
381 pub async fn create_download_url(
382 &self,
383 request: &CreateDownloadUrlRequest<'_>,
384 ) -> Result<DownloadUrlResponse, Error> {
385 let uris = paths_to_uris(&request.uris);
386 let uris_refs: Vec<&str> = uris.iter().map(|s| s.as_str()).collect();
387
388 let converted_request = CreateDownloadUrlRequest {
389 uris: uris_refs,
390 download: request.download,
391 redirect: request.redirect,
392 entity: request.entity,
393 use_primary_site_url: request.use_primary_site_url,
394 skip_error: request.skip_error,
395 archive: request.archive,
396 no_cache: request.no_cache,
397 };
398
399 let response: ApiResponse<DownloadUrlResponse> =
400 self.post("/file/url", &converted_request).await?;
401 match response.data {
402 Some(data) => Ok(data),
403 None => Err(Error::InvalidResponse(format!(
404 "API returned no data for create_download_url request: {:?}",
405 response
406 ))),
407 }
408 }
409
410 pub async fn restore_from_trash(&self, request: &RestoreFileRequest<'_>) -> Result<(), Error> {
411 let uris = paths_to_uris(&request.uris);
412 let uris_refs: Vec<&str> = uris.iter().map(|s| s.as_str()).collect();
413
414 let converted_request = RestoreFileRequest { uris: uris_refs };
415
416 let response: ApiResponse<()> = self.post("/file/restore", &converted_request).await?;
417 match response.code {
418 0 => Ok(()),
419 code => Err(Error::Api {
420 code,
421 message: response.msg,
422 }),
423 }
424 }
425
426 pub async fn force_unlock(&self, path: &str) -> Result<(), Error> {
427 let uri = path_to_uri(path);
428 let response: ApiResponse<()> = self.delete(&format!("/file/lock?uri={}", uri)).await?;
429 match response.code {
430 0 => Ok(()),
431 code => Err(Error::Api {
432 code,
433 message: response.msg,
434 }),
435 }
436 }
437
438 pub async fn patch_metadata(
439 &self,
440 path: &str,
441 request: &UpdateMetadataRequest,
442 ) -> Result<(), Error> {
443 let uri = path_to_uri(path);
444 let full_url = format!("/file/metadata?uri={}", uri);
445 let response: ApiResponse<()> = self.patch(&full_url, request).await?;
446 match response.code {
447 0 => Ok(()),
448 code => Err(Error::Api {
449 code,
450 message: response.msg,
451 }),
452 }
453 }
454
455 pub async fn mount_storage_policy(
456 &self,
457 path: &str,
458 request: &MountStoragePolicyRequest,
459 ) -> Result<(), Error> {
460 let uri = path_to_uri(path);
461 let full_url = format!("/file/policy?uri={}", uri);
462 let response: ApiResponse<()> = self.patch(&full_url, request).await?;
463 match response.code {
464 0 => Ok(()),
465 code => Err(Error::Api {
466 code,
467 message: response.msg,
468 }),
469 }
470 }
471
472 pub async fn update_view_settings(
473 &self,
474 path: &str,
475 request: &UpdateViewRequest,
476 ) -> Result<(), Error> {
477 let uri = path_to_uri(path);
478 let full_url = format!("/file/view?uri={}", uri);
479 let response: ApiResponse<()> = self.patch(&full_url, request).await?;
480 match response.code {
481 0 => Ok(()),
482 code => Err(Error::Api {
483 code,
484 message: response.msg,
485 }),
486 }
487 }
488
489 pub async fn get_file_activities(
490 &self,
491 path: &str,
492 page: Option<u32>,
493 page_size: Option<u32>,
494 ) -> Result<FileActivitiesResponse, Error> {
495 let uri = path_to_uri(path);
496 let mut url = format!("/file/activities?uri={}", uri);
497 if let Some(p) = page {
498 url.push_str(&format!("&page={}", p));
499 }
500 if let Some(ps) = page_size {
501 url.push_str(&format!("&page_size={}", ps));
502 }
503
504 let response: ApiResponse<FileActivitiesResponse> = self.get(&url).await?;
505 match response.data {
506 Some(data) => Ok(data),
507 None => Err(Error::InvalidResponse(format!(
508 "API returned no data for get_file_activities request: {:?}",
509 response
510 ))),
511 }
512 }
513
514 pub async fn get_file_info_extended(
515 &self,
516 request: &GetFileInfoRequest<'_>,
517 ) -> Result<File, Error> {
518 let uri = path_to_uri(request.uri);
519 let mut url = format!("/file/info?uri={}", uri);
520 if let Some(include_extended) = request.include_extended_info {
521 url.push_str(&format!("&extended={}", include_extended));
522 }
523
524 let response: ApiResponse<File> = self.get(&url).await?;
525 match response.data {
526 Some(data) => Ok(data),
527 None => Err(Error::InvalidResponse(format!(
528 "API returned no data for get_file_info_extended request: {:?}",
529 response
530 ))),
531 }
532 }
533
534 pub async fn get_archive_list(
535 &self,
536 request: &GetArchiveListRequest<'_>,
537 ) -> Result<ArchiveListResponse, Error> {
538 let uri = path_to_uri(request.uri);
539 let url = format!("/file/archive?uri={}", uri);
540
541 let response: ApiResponse<ArchiveListResponse> = self.get(&url).await?;
542 match response.data {
543 Some(data) => Ok(data),
544 None => Err(Error::InvalidResponse(format!(
545 "API returned no data for get_archive_list request: {:?}",
546 response
547 ))),
548 }
549 }
550}