aw_test/services/
storage.rs

1use crate::client::{Client, ParamType};
2use std::collections::HashMap;
3use crate::services::AppwriteException;
4use crate::models;
5use serde_json::json;
6use std::io::Read;
7
8#[derive(Clone)]
9pub struct Storage {
10  client: Client
11}
12
13impl Storage {  
14    pub fn new(client: &Client) -> Self {
15        Self {
16            client: client.clone()
17        }
18    }
19
20    /// Get a list of all the storage buckets. You can use the query params to
21    /// filter your results.
22    pub fn list_buckets(&self, search: Option<&str>, limit: Option<i64>, offset: Option<i64>, cursor: Option<&str>, cursor_direction: Option<&str>, order_type: Option<&str>) -> Result<models::BucketList, AppwriteException> {
23        let path = "/storage/buckets";
24        let  headers: HashMap<String, String> = [
25            ("content-type".to_string(), "application/json".to_string()),
26        ].iter().cloned().collect();
27
28        let search:&str = match search {
29            Some(data) => data,
30            None => ""
31        };
32
33        let cursor:&str = match cursor {
34            Some(data) => data,
35            None => ""
36        };
37
38        let cursor_direction:&str = match cursor_direction {
39            Some(data) => data,
40            None => ""
41        };
42
43        let order_type:&str = match order_type {
44            Some(data) => data,
45            None => ""
46        };
47
48        let  params: HashMap<String, ParamType> = [
49            ("search".to_string(), ParamType::String(search.to_string())),
50            ("limit".to_string(),  ParamType::OptionalNumber(limit)),
51            ("offset".to_string(),  ParamType::OptionalNumber(offset)),
52            ("cursor".to_string(), ParamType::String(cursor.to_string())),
53            ("cursorDirection".to_string(), ParamType::String(cursor_direction.to_string())),
54            ("orderType".to_string(), ParamType::String(order_type.to_string())),
55        ].iter().cloned().collect();
56
57        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
58
59        let processedResponse:models::BucketList = match response {
60            Ok(r) => {
61                match r.json() {
62                    Ok(json) => json,
63                    Err(e) => {
64                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
65                    }
66                }
67            }
68            Err(e) => {
69                return Err(e);
70            }
71        };
72
73        Ok(processedResponse)
74    }
75
76    /// Create a new storage bucket.
77    pub fn create_bucket(&self, bucket_id: &str, name: &str, permission: &str, read: Option<&[&str]>, write: Option<&[&str]>, enabled: Option<bool>, maximum_file_size: Option<i64>, allowed_file_extensions: Option<&[&str]>, encryption: Option<bool>, antivirus: Option<bool>) -> Result<models::Bucket, AppwriteException> {
78        let path = "/storage/buckets";
79        let  headers: HashMap<String, String> = [
80            ("content-type".to_string(), "application/json".to_string()),
81        ].iter().cloned().collect();
82
83        let read:&[&str] = match read {
84            Some(data) => data,
85            None => &[]
86        };
87
88        let write:&[&str] = match write {
89            Some(data) => data,
90            None => &[]
91        };
92
93        let allowed_file_extensions:&[&str] = match allowed_file_extensions {
94            Some(data) => data,
95            None => &[]
96        };
97
98        let  params: HashMap<String, ParamType> = [
99            ("bucketId".to_string(), ParamType::String(bucket_id.to_string())),
100            ("name".to_string(), ParamType::String(name.to_string())),
101            ("permission".to_string(), ParamType::String(permission.to_string())),
102            ("read".to_string(), ParamType::Array(read.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
103            ("write".to_string(), ParamType::Array(write.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
104            ("enabled".to_string(), ParamType::OptionalBool(enabled)),
105            ("maximumFileSize".to_string(),  ParamType::OptionalNumber(maximum_file_size)),
106            ("allowedFileExtensions".to_string(), ParamType::Array(allowed_file_extensions.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
107            ("encryption".to_string(), ParamType::OptionalBool(encryption)),
108            ("antivirus".to_string(), ParamType::OptionalBool(antivirus)),
109        ].iter().cloned().collect();
110
111        let response = self.client.clone().call("POST", &path, Some(headers), Some(params) );
112
113        let processedResponse:models::Bucket = match response {
114            Ok(r) => {
115                match r.json() {
116                    Ok(json) => json,
117                    Err(e) => {
118                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
119                    }
120                }
121            }
122            Err(e) => {
123                return Err(e);
124            }
125        };
126
127        Ok(processedResponse)
128    }
129
130    /// Get a storage bucket by its unique ID. This endpoint response returns a
131    /// JSON object with the storage bucket metadata.
132    pub fn get_bucket(&self, bucket_id: &str) -> Result<models::Bucket, AppwriteException> {
133        let path = "/storage/buckets/bucketId".replace("bucketId", &bucket_id);
134        let  headers: HashMap<String, String> = [
135            ("content-type".to_string(), "application/json".to_string()),
136        ].iter().cloned().collect();
137
138        let  params: HashMap<String, ParamType> = [
139        ].iter().cloned().collect();
140
141        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
142
143        let processedResponse:models::Bucket = match response {
144            Ok(r) => {
145                match r.json() {
146                    Ok(json) => json,
147                    Err(e) => {
148                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
149                    }
150                }
151            }
152            Err(e) => {
153                return Err(e);
154            }
155        };
156
157        Ok(processedResponse)
158    }
159
160    /// Update a storage bucket by its unique ID.
161    pub fn update_bucket(&self, bucket_id: &str, name: &str, permission: &str, read: Option<&[&str]>, write: Option<&[&str]>, enabled: Option<bool>, maximum_file_size: Option<i64>, allowed_file_extensions: Option<&[&str]>, encryption: Option<bool>, antivirus: Option<bool>) -> Result<models::Bucket, AppwriteException> {
162        let path = "/storage/buckets/bucketId".replace("bucketId", &bucket_id);
163        let  headers: HashMap<String, String> = [
164            ("content-type".to_string(), "application/json".to_string()),
165        ].iter().cloned().collect();
166
167        let read:&[&str] = match read {
168            Some(data) => data,
169            None => &[]
170        };
171
172        let write:&[&str] = match write {
173            Some(data) => data,
174            None => &[]
175        };
176
177        let allowed_file_extensions:&[&str] = match allowed_file_extensions {
178            Some(data) => data,
179            None => &[]
180        };
181
182        let  params: HashMap<String, ParamType> = [
183            ("name".to_string(), ParamType::String(name.to_string())),
184            ("permission".to_string(), ParamType::String(permission.to_string())),
185            ("read".to_string(), ParamType::Array(read.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
186            ("write".to_string(), ParamType::Array(write.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
187            ("enabled".to_string(), ParamType::OptionalBool(enabled)),
188            ("maximumFileSize".to_string(),  ParamType::OptionalNumber(maximum_file_size)),
189            ("allowedFileExtensions".to_string(), ParamType::Array(allowed_file_extensions.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
190            ("encryption".to_string(), ParamType::OptionalBool(encryption)),
191            ("antivirus".to_string(), ParamType::OptionalBool(antivirus)),
192        ].iter().cloned().collect();
193
194        let response = self.client.clone().call("PUT", &path, Some(headers), Some(params) );
195
196        let processedResponse:models::Bucket = match response {
197            Ok(r) => {
198                match r.json() {
199                    Ok(json) => json,
200                    Err(e) => {
201                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
202                    }
203                }
204            }
205            Err(e) => {
206                return Err(e);
207            }
208        };
209
210        Ok(processedResponse)
211    }
212
213    /// Delete a storage bucket by its unique ID.
214    pub fn delete_bucket(&self, bucket_id: &str) -> Result<serde_json::value::Value, AppwriteException> {
215        let path = "/storage/buckets/bucketId".replace("bucketId", &bucket_id);
216        let  headers: HashMap<String, String> = [
217            ("content-type".to_string(), "application/json".to_string()),
218        ].iter().cloned().collect();
219
220        let  params: HashMap<String, ParamType> = [
221        ].iter().cloned().collect();
222
223        let response = self.client.clone().call("DELETE", &path, Some(headers), Some(params) );
224
225        match response {
226            Ok(r) => {
227                let status_code = r.status();
228                if status_code == reqwest::StatusCode::NO_CONTENT {
229                    Ok(json!(true))
230                } else {
231                    Ok(serde_json::from_str(&r.text().unwrap()).unwrap())
232                }
233            }
234            Err(e) => {
235                Err(e)
236            }
237        }
238    }
239
240    /// Get a list of all the user files. You can use the query params to filter
241    /// your results. On admin mode, this endpoint will return a list of all of the
242    /// project's files. [Learn more about different API modes](/docs/admin).
243    pub fn list_files(&self, bucket_id: &str, search: Option<&str>, limit: Option<i64>, offset: Option<i64>, cursor: Option<&str>, cursor_direction: Option<&str>, order_type: Option<&str>) -> Result<models::FileList, AppwriteException> {
244        let path = "/storage/buckets/bucketId/files".replace("bucketId", &bucket_id);
245        let  headers: HashMap<String, String> = [
246            ("content-type".to_string(), "application/json".to_string()),
247        ].iter().cloned().collect();
248
249        let search:&str = match search {
250            Some(data) => data,
251            None => ""
252        };
253
254        let cursor:&str = match cursor {
255            Some(data) => data,
256            None => ""
257        };
258
259        let cursor_direction:&str = match cursor_direction {
260            Some(data) => data,
261            None => ""
262        };
263
264        let order_type:&str = match order_type {
265            Some(data) => data,
266            None => ""
267        };
268
269        let  params: HashMap<String, ParamType> = [
270            ("search".to_string(), ParamType::String(search.to_string())),
271            ("limit".to_string(),  ParamType::OptionalNumber(limit)),
272            ("offset".to_string(),  ParamType::OptionalNumber(offset)),
273            ("cursor".to_string(), ParamType::String(cursor.to_string())),
274            ("cursorDirection".to_string(), ParamType::String(cursor_direction.to_string())),
275            ("orderType".to_string(), ParamType::String(order_type.to_string())),
276        ].iter().cloned().collect();
277
278        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
279
280        let processedResponse:models::FileList = match response {
281            Ok(r) => {
282                match r.json() {
283                    Ok(json) => json,
284                    Err(e) => {
285                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
286                    }
287                }
288            }
289            Err(e) => {
290                return Err(e);
291            }
292        };
293
294        Ok(processedResponse)
295    }
296
297    /// Create a new file. Before using this route, you should create a new bucket
298    /// resource using either a [server
299    /// integration](/docs/server/database#storageCreateBucket) API or directly
300    /// from your Appwrite console.
301    /// 
302    /// Larger files should be uploaded using multiple requests with the
303    /// [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range)
304    /// header to send a partial request with a maximum supported chunk of `5MB`.
305    /// The `content-range` header values should always be in bytes.
306    /// 
307    /// When the first request is sent, the server will return the **File** object,
308    /// and the subsequent part request must include the file's **id** in
309    /// `x-appwrite-id` header to allow the server to know that the partial upload
310    /// is for the existing file and not for a new one.
311    /// 
312    /// If you're creating a new file using one of the Appwrite SDKs, all the
313    /// chunking logic will be managed by the SDK internally.
314    /// 
315    pub fn create_file(&self, bucket_id: &str, file_id: &str, file: std::path::PathBuf, read: Option<&[&str]>, write: Option<&[&str]>) -> Result<models::File, AppwriteException> {
316        let path = "/storage/buckets/bucketId/files".replace("bucketId", &bucket_id);
317        let mut headers: HashMap<String, String> = [
318            ("content-type".to_string(), "multipart/form-data".to_string()),
319        ].iter().cloned().collect();
320
321        let read:&[&str] = match read {
322            Some(data) => data,
323            None => &[]
324        };
325
326        let write:&[&str] = match write {
327            Some(data) => data,
328            None => &[]
329        };
330
331        let mut params: HashMap<String, ParamType> = [
332            ("fileId".to_string(), ParamType::String(file_id.to_string())),
333            ("read".to_string(), ParamType::Array(read.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
334            ("write".to_string(), ParamType::Array(write.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
335        ].iter().cloned().collect();
336
337        let mut fileBuf = std::fs::File::open(file.clone()).unwrap();
338
339        let size = fileBuf.metadata().unwrap().len();
340
341        match size {
342            size if size <= crate::client::CHUNK_SIZE => {
343                params.insert("file".to_string(), ParamType::FilePath(file));
344                match self.client.clone().call("POST", &path, Some(headers), Some(params)) {
345                    Ok(r) => {
346                        Ok(r.json::<models::File>().unwrap())
347                    }
348                    Err(e) => {
349                        Err(e)
350                    }
351                }
352            }
353            _ => {
354                // Stream Data.
355                let mut id = "".to_string();
356
357                let mut resumeCounter: u64 = 0;
358                let totalCounters = (((size / crate::client::CHUNK_SIZE) as f64).ceil() as u64) + 1;
359
360                if file_id != "unique()" {
361                    let filePath = format!("/storage/buckets/bucketId/files{}", file_id);
362                    match self.client.clone().call("GET", &filePath, Some(headers.clone()), None) {
363                        Ok(r) => {
364                            match r.json::<serde_json::Value>() {
365                                Ok(data) => {
366                                    resumeCounter = data["chunksUploaded"].as_u64().unwrap();
367                                },
368                                Err(_e) => ()
369                            };
370                        }
371                        Err(_e) => ()
372                    };
373                }
374
375                let response: reqwest::blocking::Response;
376
377                for counter in resumeCounter..totalCounters {
378                    let mut headers: HashMap<String, String> = [
379                        ("content-type".to_string(), "multipart/form-data".to_string()),
380                    ].iter().cloned().collect();
381
382                    let mut params = params.clone();
383
384                    headers.insert("content-range".to_string(), format!("bytes {}-{}/{}", (counter * crate::client::CHUNK_SIZE),
385                        std::cmp::min((counter * crate::client::CHUNK_SIZE) + crate::client::CHUNK_SIZE - 1, size), size));
386
387                    if id.len() != 0 {
388                        headers.insert("x-appwrite-id".to_string(), id.to_string());
389                    }
390
391                    let mut chunk = Vec::with_capacity(crate::client::CHUNK_SIZE as usize);
392
393                    match fileBuf.by_ref().take(crate::client::CHUNK_SIZE).read_to_end(&mut chunk) {
394                        Ok(_) => (),
395                        Err(e) => {
396                            return Err(AppwriteException::new(format!("A error occoured. ERR: {}, This could either be a connection error or an internal Appwrite error. Please check your Appwrite instance logs. ", e), 0, "".to_string()))
397                        }
398                    };
399
400                    params.insert("file".to_string(), ParamType::StreamData(chunk, file.file_name().unwrap().to_string_lossy().to_string()));
401
402                    let response = match self.client.clone().call("POST", &path, Some(headers), Some(params)) {
403                        Ok(r) => r,
404                        Err(e) => {
405                            return Err(e);
406                        }
407                    };
408
409                    // If last chunk, return the response.
410                    if counter == totalCounters - 1 {
411                        return Ok(response.json::<models::File>().unwrap());
412                    } else {
413                        if id.len() == 0 {
414                            id = response.json::<serde_json::Value>().unwrap()["$id"].as_str().unwrap().to_owned();
415                        }
416                    }
417                };
418
419                return Err(AppwriteException::new("Error uploading chunk data.".to_string(), 500, "0".to_string()));
420            }
421        }
422    }
423
424    /// Get a file by its unique ID. This endpoint response returns a JSON object
425    /// with the file metadata.
426    pub fn get_file(&self, bucket_id: &str, file_id: &str) -> Result<models::File, AppwriteException> {
427        let path = "/storage/buckets/bucketId/files/fileId".replace("bucketId", &bucket_id).replace("fileId", &file_id);
428        let  headers: HashMap<String, String> = [
429            ("content-type".to_string(), "application/json".to_string()),
430        ].iter().cloned().collect();
431
432        let  params: HashMap<String, ParamType> = [
433        ].iter().cloned().collect();
434
435        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
436
437        let processedResponse:models::File = match response {
438            Ok(r) => {
439                match r.json() {
440                    Ok(json) => json,
441                    Err(e) => {
442                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
443                    }
444                }
445            }
446            Err(e) => {
447                return Err(e);
448            }
449        };
450
451        Ok(processedResponse)
452    }
453
454    /// Update a file by its unique ID. Only users with write permissions have
455    /// access to update this resource.
456    pub fn update_file(&self, bucket_id: &str, file_id: &str, read: Option<&[&str]>, write: Option<&[&str]>) -> Result<models::File, AppwriteException> {
457        let path = "/storage/buckets/bucketId/files/fileId".replace("bucketId", &bucket_id).replace("fileId", &file_id);
458        let  headers: HashMap<String, String> = [
459            ("content-type".to_string(), "application/json".to_string()),
460        ].iter().cloned().collect();
461
462        let read:&[&str] = match read {
463            Some(data) => data,
464            None => &[]
465        };
466
467        let write:&[&str] = match write {
468            Some(data) => data,
469            None => &[]
470        };
471
472        let  params: HashMap<String, ParamType> = [
473            ("read".to_string(), ParamType::Array(read.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
474            ("write".to_string(), ParamType::Array(write.into_iter().map(|x| ParamType::String(x.to_string())).collect())),
475        ].iter().cloned().collect();
476
477        let response = self.client.clone().call("PUT", &path, Some(headers), Some(params) );
478
479        let processedResponse:models::File = match response {
480            Ok(r) => {
481                match r.json() {
482                    Ok(json) => json,
483                    Err(e) => {
484                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
485                    }
486                }
487            }
488            Err(e) => {
489                return Err(e);
490            }
491        };
492
493        Ok(processedResponse)
494    }
495
496    /// Delete a file by its unique ID. Only users with write permissions have
497    /// access to delete this resource.
498    pub fn delete_file(&self, bucket_id: &str, file_id: &str) -> Result<serde_json::value::Value, AppwriteException> {
499        let path = "/storage/buckets/bucketId/files/fileId".replace("bucketId", &bucket_id).replace("fileId", &file_id);
500        let  headers: HashMap<String, String> = [
501            ("content-type".to_string(), "application/json".to_string()),
502        ].iter().cloned().collect();
503
504        let  params: HashMap<String, ParamType> = [
505        ].iter().cloned().collect();
506
507        let response = self.client.clone().call("DELETE", &path, Some(headers), Some(params) );
508
509        match response {
510            Ok(r) => {
511                let status_code = r.status();
512                if status_code == reqwest::StatusCode::NO_CONTENT {
513                    Ok(json!(true))
514                } else {
515                    Ok(serde_json::from_str(&r.text().unwrap()).unwrap())
516                }
517            }
518            Err(e) => {
519                Err(e)
520            }
521        }
522    }
523
524    /// Get a file content by its unique ID. The endpoint response return with a
525    /// 'Content-Disposition: attachment' header that tells the browser to start
526    /// downloading the file to user downloads directory.
527    pub fn get_file_download(&self, bucket_id: &str, file_id: &str) -> Result<Vec<u8>, AppwriteException> {
528        let path = "/storage/buckets/bucketId/files/fileId/download".replace("bucketId", &bucket_id).replace("fileId", &file_id);
529        let  headers: HashMap<String, String> = [
530            ("content-type".to_string(), "application/json".to_string()),
531        ].iter().cloned().collect();
532
533        let  params: HashMap<String, ParamType> = [
534        ].iter().cloned().collect();
535
536        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
537
538        let processedResponse:Vec<u8> = match response {
539            Ok(mut r) => {
540                let mut buf: Vec<u8> = vec![];
541                match r.copy_to(&mut buf) {
542                    Ok(_) => (),
543                    Err(e) => {
544                        return Err(AppwriteException::new(format!("Error copying response to buffer: {}", e), 0, "".to_string()));
545                    }
546                };
547                buf
548            }
549            Err(e) => {
550                return Err(e);
551            }
552        };
553
554        Ok(processedResponse)
555    }
556
557    /// Get a file preview image. Currently, this method supports preview for image
558    /// files (jpg, png, and gif), other supported formats, like pdf, docs, slides,
559    /// and spreadsheets, will return the file icon image. You can also pass query
560    /// string arguments for cutting and resizing your preview image. Preview is
561    /// supported only for image files smaller than 10MB.
562    pub fn get_file_preview(&self, bucket_id: &str, file_id: &str, width: Option<i64>, height: Option<i64>, gravity: Option<&str>, quality: Option<i64>, border_width: Option<i64>, border_color: Option<&str>, border_radius: Option<i64>, opacity: Option<f64>, rotation: Option<i64>, background: Option<&str>, output: Option<&str>) -> Result<Vec<u8>, AppwriteException> {
563        let path = "/storage/buckets/bucketId/files/fileId/preview".replace("bucketId", &bucket_id).replace("fileId", &file_id);
564        let  headers: HashMap<String, String> = [
565            ("content-type".to_string(), "application/json".to_string()),
566        ].iter().cloned().collect();
567
568        let gravity:&str = match gravity {
569            Some(data) => data,
570            None => ""
571        };
572
573        let border_color:&str = match border_color {
574            Some(data) => data,
575            None => ""
576        };
577
578        let background:&str = match background {
579            Some(data) => data,
580            None => ""
581        };
582
583        let output:&str = match output {
584            Some(data) => data,
585            None => ""
586        };
587
588        let  params: HashMap<String, ParamType> = [
589            ("width".to_string(),  ParamType::OptionalNumber(width)),
590            ("height".to_string(),  ParamType::OptionalNumber(height)),
591            ("gravity".to_string(), ParamType::String(gravity.to_string())),
592            ("quality".to_string(),  ParamType::OptionalNumber(quality)),
593            ("borderWidth".to_string(),  ParamType::OptionalNumber(border_width)),
594            ("borderColor".to_string(), ParamType::String(border_color.to_string())),
595            ("borderRadius".to_string(),  ParamType::OptionalNumber(border_radius)),
596            ("opacity".to_string(),  ParamType::OptionalFloat(opacity)),
597            ("rotation".to_string(),  ParamType::OptionalNumber(rotation)),
598            ("background".to_string(), ParamType::String(background.to_string())),
599            ("output".to_string(), ParamType::String(output.to_string())),
600        ].iter().cloned().collect();
601
602        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
603
604        let processedResponse:Vec<u8> = match response {
605            Ok(mut r) => {
606                let mut buf: Vec<u8> = vec![];
607                match r.copy_to(&mut buf) {
608                    Ok(_) => (),
609                    Err(e) => {
610                        return Err(AppwriteException::new(format!("Error copying response to buffer: {}", e), 0, "".to_string()));
611                    }
612                };
613                buf
614            }
615            Err(e) => {
616                return Err(e);
617            }
618        };
619
620        Ok(processedResponse)
621    }
622
623    /// Get a file content by its unique ID. This endpoint is similar to the
624    /// download method but returns with no  'Content-Disposition: attachment'
625    /// header.
626    pub fn get_file_view(&self, bucket_id: &str, file_id: &str) -> Result<Vec<u8>, AppwriteException> {
627        let path = "/storage/buckets/bucketId/files/fileId/view".replace("bucketId", &bucket_id).replace("fileId", &file_id);
628        let  headers: HashMap<String, String> = [
629            ("content-type".to_string(), "application/json".to_string()),
630        ].iter().cloned().collect();
631
632        let  params: HashMap<String, ParamType> = [
633        ].iter().cloned().collect();
634
635        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
636
637        let processedResponse:Vec<u8> = match response {
638            Ok(mut r) => {
639                let mut buf: Vec<u8> = vec![];
640                match r.copy_to(&mut buf) {
641                    Ok(_) => (),
642                    Err(e) => {
643                        return Err(AppwriteException::new(format!("Error copying response to buffer: {}", e), 0, "".to_string()));
644                    }
645                };
646                buf
647            }
648            Err(e) => {
649                return Err(e);
650            }
651        };
652
653        Ok(processedResponse)
654    }
655
656    pub fn get_usage(&self, range: Option<&str>) -> Result<models::UsageStorage, AppwriteException> {
657        let path = "/storage/usage";
658        let  headers: HashMap<String, String> = [
659            ("content-type".to_string(), "application/json".to_string()),
660        ].iter().cloned().collect();
661
662        let range:&str = match range {
663            Some(data) => data,
664            None => ""
665        };
666
667        let  params: HashMap<String, ParamType> = [
668            ("range".to_string(), ParamType::String(range.to_string())),
669        ].iter().cloned().collect();
670
671        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
672
673        let processedResponse:models::UsageStorage = match response {
674            Ok(r) => {
675                match r.json() {
676                    Ok(json) => json,
677                    Err(e) => {
678                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
679                    }
680                }
681            }
682            Err(e) => {
683                return Err(e);
684            }
685        };
686
687        Ok(processedResponse)
688    }
689
690    pub fn get_bucket_usage(&self, bucket_id: &str, range: Option<&str>) -> Result<models::UsageBuckets, AppwriteException> {
691        let path = "/storage/bucketId/usage".replace("bucketId", &bucket_id);
692        let  headers: HashMap<String, String> = [
693            ("content-type".to_string(), "application/json".to_string()),
694        ].iter().cloned().collect();
695
696        let range:&str = match range {
697            Some(data) => data,
698            None => ""
699        };
700
701        let  params: HashMap<String, ParamType> = [
702            ("range".to_string(), ParamType::String(range.to_string())),
703        ].iter().cloned().collect();
704
705        let response = self.client.clone().call("GET", &path, Some(headers), Some(params) );
706
707        let processedResponse:models::UsageBuckets = match response {
708            Ok(r) => {
709                match r.json() {
710                    Ok(json) => json,
711                    Err(e) => {
712                        return Err(AppwriteException::new(format!("Error parsing response json: {}", e), 0, "".to_string()));
713                    }
714                }
715            }
716            Err(e) => {
717                return Err(e);
718            }
719        };
720
721        Ok(processedResponse)
722    }
723}