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 _: ApiResponse<()> = self.post("/file/move", request).await?;
92 Ok(())
93 }
94
95 pub async fn copy_file(&self, request: &CopyFileRequest<'_>) -> Result<(), Error> {
96 let _: ApiResponse<()> = self.post("/file/copy", request).await?;
97 Ok(())
98 }
99
100 pub async fn rename_file(
101 &self,
102 file_path: &str,
103 request: &RenameFileRequest<'_>,
104 ) -> Result<(), Error> {
105 let uri = path_to_uri(file_path);
108 let new_uri = if let Some(parent) = file_path.rsplit('/').nth(1) {
109 if parent.is_empty() {
110 path_to_uri(&format!("/{}", request.name))
112 } else {
113 path_to_uri(&format!("{}/{}", parent, request.name))
114 }
115 } else {
116 path_to_uri(&format!("/{}", request.name))
117 };
118
119 let move_req = MoveFileRequest {
120 from: &uri,
121 to: &new_uri,
122 };
123 self.move_file(&move_req).await
124 }
125
126 pub async fn delete_file(&self, file_path: &str) -> Result<(), Error> {
127 let uri = path_to_uri(file_path);
129 let url = format!("/file?uri={}", uri);
130 let _: ApiResponse<()> = self.delete(&url).await?;
131 Ok(())
132 }
133
134 pub async fn create_directory(&self, path: &str) -> Result<(), Error> {
135 let uri = path_to_uri(path);
137
138 let request = serde_json::json!({
140 "uri": uri,
141 "type": "folder"
142 });
143
144 let response: ApiResponse<serde_json::Value> = self.post("/file/create", &request).await?;
145 match response.code {
146 0 => Ok(()),
147 code => Err(Error::Api {
148 code,
149 message: response.msg,
150 }),
151 }
152 }
153
154 pub async fn set_file_permission(
155 &self,
156 request: &SetFilePermissionRequest<'_>,
157 ) -> Result<(), Error> {
158 let _: ApiResponse<()> = self.post("/file/permission", request).await?;
159 Ok(())
160 }
161
162 pub async fn delete_file_permission(&self, path: &str) -> Result<(), Error> {
163 let uri = path_to_uri(path);
164 let _: ApiResponse<()> = self
165 .delete(&format!("/file/permission?uri={}", uri))
166 .await?;
167 Ok(())
168 }
169
170 pub async fn create_upload_session(
171 &self,
172 request: &CreateUploadSessionRequest<'_>,
173 ) -> Result<UploadSessionResponse, Error> {
174 let response: ApiResponse<UploadSessionResponse> =
175 self.put("/file/upload", request).await?;
176 match response.data {
177 Some(data) => Ok(data),
178 None => Err(Error::InvalidResponse(format!(
179 "API returned no data for create_upload_session request: {:?}",
180 response
181 ))),
182 }
183 }
184
185 pub async fn upload_file_chunk(
186 &self,
187 session_id: &str,
188 index: u32,
189 chunk_data: &[u8],
190 ) -> Result<(), Error> {
191 let url = format!("/file/upload/{}/{}", session_id, index);
192 let full_url = self.get_url(&url);
193
194 let mut request = self.http_client.post(&full_url).body(chunk_data.to_vec());
195
196 if let Some(token) = &self.token {
197 request = request.bearer_auth(token);
198 }
199
200 let response = request.send().await?;
201 let status = response.status();
202
203 if !status.is_success() {
204 let error_text = response
205 .text()
206 .await
207 .unwrap_or_else(|_| "Unknown error".to_string());
208 return Err(Error::Api {
209 code: status.as_u16() as i32,
210 message: error_text,
211 });
212 }
213
214 Ok(())
215 }
216
217 pub async fn delete_upload_session(&self, path: &str, session_id: &str) -> Result<(), Error> {
218 let uri = path_to_uri(path);
219 let request = DeleteUploadSessionRequest {
220 id: session_id,
221 uri: &uri,
222 };
223 let url = self.get_url("/file/upload");
224
225 let body = serde_json::to_string(&request)?;
226
227 let mut http_req = self.http_client.delete(&url);
228 if let Some(token) = &self.token {
229 http_req = http_req.bearer_auth(token);
230 }
231
232 let response = http_req
233 .header("Content-Type", "application/json")
234 .body(body)
235 .send()
236 .await?;
237
238 let status = response.status();
239 if !status.is_success() {
240 let error_text = response
241 .text()
242 .await
243 .unwrap_or_else(|_| "Unknown error".to_string());
244 return Err(Error::Api {
245 code: status.as_u16() as i32,
246 message: error_text,
247 });
248 }
249
250 Ok(())
251 }
252
253 pub async fn get_thumbnail_url(
254 &self,
255 path: &str,
256 width: Option<u32>,
257 height: Option<u32>,
258 ) -> Result<String, Error> {
259 let uri = path_to_uri(path);
260 let mut url = format!("/file/thumb?uri={}", uri);
261 if let Some(w) = width {
262 url.push_str(&format!("&width={}", w));
263 }
264 if let Some(h) = height {
265 url.push_str(&format!("&height={}", h));
266 }
267
268 let response: ApiResponse<String> = self.get(&url).await?;
269 match response.data {
270 Some(data) => Ok(data),
271 None => Err(Error::InvalidResponse(format!(
272 "API returned no data for get_thumbnail_url request: {:?}",
273 response
274 ))),
275 }
276 }
277
278 pub async fn get_file_content(&self, path: &str) -> Result<String, Error> {
279 let uri = path_to_uri(path);
280 let response: ApiResponse<String> = self.get(&format!("/file/content?uri={}", uri)).await?;
281 match response.data {
282 Some(data) => Ok(data),
283 None => Err(Error::InvalidResponse(format!(
284 "API returned no data for get_file_content request: {:?}",
285 response
286 ))),
287 }
288 }
289
290 pub async fn update_file_content(
291 &self,
292 request: &UpdateFileContentRequest<'_>,
293 ) -> Result<(), Error> {
294 let _: ApiResponse<()> = self.put("/file/content", request).await?;
295 Ok(())
296 }
297
298 pub async fn create_viewer_session(
299 &self,
300 request: &CreateViewerSessionRequest<'_>,
301 ) -> Result<ViewerSessionResponse, Error> {
302 let response: ApiResponse<ViewerSessionResponse> =
303 self.put("/file/viewerSession", request).await?;
304 match response.data {
305 Some(data) => Ok(data),
306 None => Err(Error::InvalidResponse(format!(
307 "API returned no data for create_viewer_session request: {:?}",
308 response
309 ))),
310 }
311 }
312
313 pub async fn create_file(&self, request: &CreateFileRequest<'_>) -> Result<File, Error> {
314 let response: ApiResponse<File> = self.post("/file/create", request).await?;
315 match response.data {
316 Some(data) => Ok(data),
317 None => Err(Error::InvalidResponse(format!(
318 "API returned no data for create_file request: {:?}",
319 response
320 ))),
321 }
322 }
323
324 pub async fn rename_multiple(&self, request: &RenameMultipleRequest<'_>) -> Result<(), Error> {
325 let _: ApiResponse<()> = self.post("/file/rename", request).await?;
326 Ok(())
327 }
328
329 pub async fn move_copy_files(&self, request: &MoveCopyFileRequest<'_>) -> Result<(), Error> {
330 let _: ApiResponse<()> = self.post("/file/move", request).await?;
331 Ok(())
332 }
333
334 pub async fn create_download_url(
335 &self,
336 request: &CreateDownloadUrlRequest<'_>,
337 ) -> Result<DownloadUrlResponse, Error> {
338 let uris = paths_to_uris(&request.uris);
339 let uris_refs: Vec<&str> = uris.iter().map(|s| s.as_str()).collect();
340
341 let converted_request = CreateDownloadUrlRequest {
342 uris: uris_refs,
343 download: request.download,
344 redirect: request.redirect,
345 entity: request.entity,
346 use_primary_site_url: request.use_primary_site_url,
347 skip_error: request.skip_error,
348 archive: request.archive,
349 no_cache: request.no_cache,
350 };
351
352 let response: ApiResponse<DownloadUrlResponse> =
353 self.post("/file/url", &converted_request).await?;
354 match response.data {
355 Some(data) => Ok(data),
356 None => Err(Error::InvalidResponse(format!(
357 "API returned no data for create_download_url request: {:?}",
358 response
359 ))),
360 }
361 }
362
363 pub async fn restore_from_trash(&self, request: &RestoreFileRequest<'_>) -> Result<(), Error> {
364 let uris = paths_to_uris(&request.uris);
365 let uris_refs: Vec<&str> = uris.iter().map(|s| s.as_str()).collect();
366
367 let converted_request = RestoreFileRequest { uris: uris_refs };
368
369 let _: ApiResponse<()> = self.post("/file/restore", &converted_request).await?;
370 Ok(())
371 }
372
373 pub async fn force_unlock(&self, path: &str) -> Result<(), Error> {
374 let uri = path_to_uri(path);
375 let _: ApiResponse<()> = self.delete(&format!("/file/lock?uri={}", uri)).await?;
376 Ok(())
377 }
378
379 pub async fn patch_metadata(
380 &self,
381 path: &str,
382 request: &UpdateMetadataRequest,
383 ) -> Result<(), Error> {
384 let uri = path_to_uri(path);
385 let full_url = format!("/file/metadata?uri={}", uri);
386 let _: ApiResponse<()> = self.patch(&full_url, request).await?;
387 Ok(())
388 }
389
390 pub async fn mount_storage_policy(
391 &self,
392 path: &str,
393 request: &MountStoragePolicyRequest,
394 ) -> Result<(), Error> {
395 let uri = path_to_uri(path);
396 let full_url = format!("/file/policy?uri={}", uri);
397 let _: ApiResponse<()> = self.patch(&full_url, request).await?;
398 Ok(())
399 }
400
401 pub async fn update_view_settings(
402 &self,
403 path: &str,
404 request: &UpdateViewRequest,
405 ) -> Result<(), Error> {
406 let uri = path_to_uri(path);
407 let full_url = format!("/file/view?uri={}", uri);
408 let _: ApiResponse<()> = self.patch(&full_url, request).await?;
409 Ok(())
410 }
411
412 pub async fn get_file_activities(
413 &self,
414 path: &str,
415 page: Option<u32>,
416 page_size: Option<u32>,
417 ) -> Result<FileActivitiesResponse, Error> {
418 let uri = path_to_uri(path);
419 let mut url = format!("/file/activities?uri={}", uri);
420 if let Some(p) = page {
421 url.push_str(&format!("&page={}", p));
422 }
423 if let Some(ps) = page_size {
424 url.push_str(&format!("&page_size={}", ps));
425 }
426
427 let response: ApiResponse<FileActivitiesResponse> = self.get(&url).await?;
428 match response.data {
429 Some(data) => Ok(data),
430 None => Err(Error::InvalidResponse(format!(
431 "API returned no data for get_file_activities request: {:?}",
432 response
433 ))),
434 }
435 }
436
437 pub async fn get_file_info_extended(
438 &self,
439 request: &GetFileInfoRequest<'_>,
440 ) -> Result<File, Error> {
441 let uri = path_to_uri(request.uri);
442 let mut url = format!("/file/info?uri={}", uri);
443 if let Some(include_extended) = request.include_extended_info {
444 url.push_str(&format!("&extended={}", include_extended));
445 }
446
447 let response: ApiResponse<File> = self.get(&url).await?;
448 match response.data {
449 Some(data) => Ok(data),
450 None => Err(Error::InvalidResponse(format!(
451 "API returned no data for get_file_info_extended request: {:?}",
452 response
453 ))),
454 }
455 }
456
457 pub async fn get_archive_list(
458 &self,
459 request: &GetArchiveListRequest<'_>,
460 ) -> Result<ArchiveListResponse, Error> {
461 let uri = path_to_uri(request.uri);
462 let url = format!("/file/archive?uri={}", uri);
463
464 let response: ApiResponse<ArchiveListResponse> = self.get(&url).await?;
465 match response.data {
466 Some(data) => Ok(data),
467 None => Err(Error::InvalidResponse(format!(
468 "API returned no data for get_archive_list request: {:?}",
469 response
470 ))),
471 }
472 }
473}