cloud_storage/sync/
object.rs

1use crate::{
2    object::{ComposeRequest, ObjectList},
3    ListRequest, Object,
4};
5use futures_util::TryStreamExt;
6
7/// Operations on [`Object`](Object)s.
8#[derive(Debug)]
9pub struct ObjectClient<'a>(pub(super) &'a super::Client);
10
11impl<'a> ObjectClient<'a> {
12    /// Create a new object.
13    /// Upload a file as that is loaded in memory to google cloud storage, where it will be
14    /// interpreted according to the mime type you specified.
15    /// ## Example
16    /// ```rust,no_run
17    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
18    /// # fn read_cute_cat(_in: &str) -> Vec<u8> { vec![0, 1] }
19    /// use cloud_storage::sync::Client;
20    /// use cloud_storage::Object;
21    ///
22    /// let file: Vec<u8> = read_cute_cat("cat.png");
23    /// let client = Client::new()?;
24    /// client.object().create("cat-photos", file, "recently read cat.png", "image/png")?;
25    /// # Ok(())
26    /// # }
27    /// ```
28    pub fn create(
29        &self,
30        bucket: &str,
31        file: Vec<u8>,
32        filename: &str,
33        mime_type: &str,
34    ) -> crate::Result<Object> {
35        self.0.runtime.block_on(
36            self.0
37                .client
38                .object()
39                .create(bucket, file, filename, mime_type),
40        )
41    }
42
43    /// Create a new object. This works in the same way as `ObjectClient::create`, except it does not need
44    /// to load the entire file in ram.
45    pub fn create_streamed<R>(
46        &self,
47        bucket: &str,
48        file: R,
49        length: impl Into<Option<u64>>,
50        filename: &str,
51        mime_type: &str,
52    ) -> crate::Result<Object>
53    where
54        R: std::io::Read + Send + Sync + Unpin + 'static,
55    {
56        let stream = super::helpers::ReaderStream::new(file);
57
58        self.0.runtime.block_on(
59            self.0
60                .client
61                .object()
62                .create_streamed(bucket, stream, length, filename, mime_type),
63        )
64    }
65
66    /// Obtain a list of objects within this Bucket.
67    /// ### Example
68    /// ```no_run
69    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
70    /// use cloud_storage::sync::Client;
71    /// use cloud_storage::{Object, ListRequest};
72    ///
73    /// let client = Client::new()?;
74    /// let all_objects = client.object().list("my_bucket", ListRequest::default())?;
75    /// # Ok(())
76    /// # }
77    /// ```
78    pub fn list(
79        &self,
80        bucket: &'a str,
81        list_request: ListRequest,
82    ) -> crate::Result<Vec<ObjectList>> {
83        let rt = &self.0.runtime;
84        let listed = rt.block_on(self.0.client.object().list(bucket, list_request))?;
85        rt.block_on(listed.try_collect())
86    }
87
88    /// Obtains a single object with the specified name in the specified bucket.
89    /// ### Example
90    /// ```no_run
91    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
92    /// use cloud_storage::sync::Client;
93    /// use cloud_storage::Object;
94    ///
95    /// let client = Client::new()?;
96    /// let object = client.object().read("my_bucket", "path/to/my/file.png")?;
97    /// # Ok(())
98    /// # }
99    /// ```
100    pub fn read(&self, bucket: &str, file_name: &str) -> crate::Result<Object> {
101        self.0
102            .runtime
103            .block_on(self.0.client.object().read(bucket, file_name))
104    }
105
106    /// Download the content of the object with the specified name in the specified bucket.
107    /// ### Example
108    /// ```no_run
109    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
110    /// use cloud_storage::sync::Client;
111    /// use cloud_storage::Object;
112    ///
113    /// let client = Client::new()?;
114    /// let bytes = client.object().download("my_bucket", "path/to/my/file.png")?;
115    /// # Ok(())
116    /// # }
117    /// ```
118    pub fn download(&self, bucket: &str, file_name: &str) -> crate::Result<Vec<u8>> {
119        self.0
120            .runtime
121            .block_on(self.0.client.object().download(bucket, file_name))
122    }
123
124    /// Obtains a single object with the specified name in the specified bucket.
125    /// ### Example
126    /// ```no_run
127    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
128    /// use cloud_storage::sync::Client;
129    /// use cloud_storage::Object;
130    ///
131    /// let client = Client::new()?;
132    /// let mut object = client.object().read("my_bucket", "path/to/my/file.png")?;
133    /// object.content_type = Some("application/xml".to_string());
134    /// client.object().update(&object)?;
135    /// # Ok(())
136    /// # }
137    /// ```
138    pub fn update(&self, object: &Object) -> crate::Result<Object> {
139        self.0
140            .runtime
141            .block_on(self.0.client.object().update(object))
142    }
143
144    /// Deletes a single object with the specified name in the specified bucket.
145    /// ### Example
146    /// ```no_run
147    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
148    /// use cloud_storage::sync::Client;
149    /// use cloud_storage::Object;
150    ///
151    /// let client = Client::new()?;
152    /// client.object().delete("my_bucket", "path/to/my/file.png")?;
153    /// # Ok(())
154    /// # }
155    /// ```
156    pub fn delete(&self, bucket: &str, file_name: &str) -> crate::Result<()> {
157        self.0
158            .runtime
159            .block_on(self.0.client.object().delete(bucket, file_name))
160    }
161
162    /// Obtains a single object with the specified name in the specified bucket.
163    /// ### Example
164    /// ```no_run
165    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
166    /// use cloud_storage::sync::Client;
167    /// use cloud_storage::object::{Object, ComposeRequest, SourceObject};
168    ///
169    /// let client = Client::new()?;
170    /// let obj1 = client.object().read("my_bucket", "file1")?;
171    /// let obj2 = client.object().read("my_bucket", "file2")?;
172    /// let compose_request = ComposeRequest {
173    ///     kind: "storage#composeRequest".to_string(),
174    ///     source_objects: vec![
175    ///         SourceObject {
176    ///             name: obj1.name.clone(),
177    ///             generation: None,
178    ///             object_preconditions: None,
179    ///         },
180    ///         SourceObject {
181    ///             name: obj2.name.clone(),
182    ///             generation: None,
183    ///             object_preconditions: None,
184    ///         },
185    ///     ],
186    ///     destination: None,
187    /// };
188    /// let obj3 = client.object().compose("my_bucket", &compose_request, "test-concatted-file")?;
189    /// // obj3 is now a file with the content of obj1 and obj2 concatted together.
190    /// # Ok(())
191    /// # }
192    /// ```
193    pub fn compose(
194        &self,
195        bucket: &str,
196        req: &ComposeRequest,
197        destination_object: &str,
198    ) -> crate::Result<Object> {
199        self.0.runtime.block_on(
200            self.0
201                .client
202                .object()
203                .compose(bucket, req, destination_object),
204        )
205    }
206
207    /// Copy this object to the target bucket and path
208    /// ### Example
209    /// ```no_run
210    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
211    /// use cloud_storage::sync::Client;
212    /// use cloud_storage::object::{Object, ComposeRequest};
213    ///
214    /// let client = Client::new()?;
215    /// let obj1 = client.object().read("my_bucket", "file1")?;
216    /// let obj2 = client.object().copy(&obj1, "my_other_bucket", "file2")?;
217    /// // obj2 is now a copy of obj1.
218    /// # Ok(())
219    /// # }
220    /// ```
221    pub fn copy(
222        &self,
223        object: &Object,
224        destination_bucket: &str,
225        path: &str,
226    ) -> crate::Result<Object> {
227        self.0.runtime.block_on(
228            self.0
229                .client
230                .object()
231                .copy(object, destination_bucket, path),
232        )
233    }
234
235    /// Moves a file from the current location to the target bucket and path.
236    ///
237    /// ## Limitations
238    /// This function does not yet support rewriting objects to another
239    /// * Geographical Location,
240    /// * Encryption,
241    /// * Storage class.
242    /// These limitations mean that for now, the rewrite and the copy methods do the same thing.
243    /// ### Example
244    /// ```no_run
245    /// # fn main() -> Result<(), Box<dyn std::error::Error>> {
246    /// use cloud_storage::sync::Client;
247    /// use cloud_storage::object::Object;
248    ///
249    /// let client = Client::new()?;
250    /// let obj1 = client.object().read("my_bucket", "file1")?;
251    /// let obj2 = client.object().rewrite(&obj1, "my_other_bucket", "file2")?;
252    /// // obj2 is now a copy of obj1.
253    /// # Ok(())
254    /// # }
255    /// ```
256    pub fn rewrite(
257        &self,
258        object: &Object,
259        destination_bucket: &str,
260        path: &str,
261    ) -> crate::Result<Object> {
262        self.0.runtime.block_on(
263            self.0
264                .client
265                .object()
266                .rewrite(object, destination_bucket, path),
267        )
268    }
269}