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}