Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,14 @@ let new_bucket = NewBucket { name: "mybucket", ..Default::default() }
let bucket = Bucket::create(new_bucket).await?;
// upload a file to our new bucket
let content = b"Your file is now on google cloud storage!";
bucket.upload(content, "folder/filename.txt", "application/text").await?;
let mut object = Object::create("mybucket", content, "folder/filename.txt", "application/text").await?;
bucket.upload(content, "folder/filename.txt", "application/text", None).await?;
let mut object = Object::create("mybucket", content, "folder/filename.txt", "application/text", None).await?;
// let's copy the file
object.copy("mybucket2: electric boogaloo", "otherfolder/filename.txt").await?;
object.copy("mybucket2: electric boogaloo", "otherfolder/filename.txt", None).await?;
// print a link to the file
println!("{}", object.download_url(1000)); // download link for 1000 seconds
// remove the file from the bucket
object.delete().await?;
object.delete(None).await?;
```

Authorization can be granted using the `SERVICE_ACCOUNT` or `GOOGLE_APPLICATION_CREDENTIALS` environment variable, which should contain path to the `service-account-*******.json` file that contains the Google credentials. Alternatively, the service account credentials can be provided as JSON directly through the `SERVICE_ACCOUNT_JSON` or `GOOGLE_APPLICATION_CREDENTIALS_JSON` environment variable, which is useful when providing secrets in CI or k8s.
Expand Down
80 changes: 60 additions & 20 deletions src/client/object.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ use reqwest::StatusCode;

use crate::{
error::GoogleResponse,
object::{percent_encode, ComposeRequest, ObjectList, RewriteResponse, SizedByteStream},
object::{
percent_encode, ComposeParameters, ComposeRequest, CopyParameters, CreateParameters,
DeleteParameters, ObjectList, ReadParameters, RewriteParameters, RewriteResponse,
SizedByteStream, UpdateParameters,
},
ListRequest, Object,
};

Expand All @@ -28,7 +32,7 @@ impl<'a> ObjectClient<'a> {
///
/// let file: Vec<u8> = read_cute_cat("cat.png");
/// let client = Client::default();
/// client.object().create("cat-photos", file, "recently read cat.png", "image/png").await?;
/// client.object().create("cat-photos", file, "recently read cat.png", "image/png", None).await?;
/// # Ok(())
/// # }
/// ```
Expand All @@ -38,6 +42,7 @@ impl<'a> ObjectClient<'a> {
file: Vec<u8>,
filename: &str,
mime_type: &str,
parameters: Option<CreateParameters>,
) -> crate::Result<Object> {
use reqwest::header::{CONTENT_LENGTH, CONTENT_TYPE};

Expand All @@ -54,6 +59,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.post(url)
.query(&parameters)
.headers(headers)
.body(file)
.send()
Expand All @@ -80,7 +86,7 @@ impl<'a> ObjectClient<'a> {
/// .send()
/// .await?
/// .bytes_stream();
/// client.object().create_streamed("cat-photos", file, 10, "recently read cat.png", "image/png").await?;
/// client.object().create_streamed("cat-photos", file, 10, "recently read cat.png", "image/png", None).await?;
/// # Ok(())
/// # }
/// ```
Expand All @@ -91,6 +97,7 @@ impl<'a> ObjectClient<'a> {
length: impl Into<Option<u64>>,
filename: &str,
mime_type: &str,
parameters: Option<CreateParameters>,
) -> crate::Result<Object>
where
S: TryStream + Send + Sync + 'static,
Expand All @@ -116,6 +123,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.post(url)
.query(&parameters)
.headers(headers)
.body(body)
.send()
Expand Down Expand Up @@ -236,11 +244,17 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::Object;
///
/// let client = Client::default();
/// let object = client.object().read("my_bucket", "path/to/my/file.png").await?;
/// let object = client.object().read("my_bucket", "path/to/my/file.png", None).await?;
/// # Ok(())
/// # }
/// ```
pub async fn read(&self, bucket: &str, file_name: &str) -> crate::Result<Object> {
pub async fn read(
&self,
bucket: &str,
file_name: &str,
parameters: Option<ReadParameters>,
) -> crate::Result<Object> {
//let paramters = qs::
let url = format!(
"{}/b/{}/o/{}",
crate::BASE_URL,
Expand All @@ -251,6 +265,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.get(&url)
.query(&parameters)
.headers(self.0.get_headers().await?)
.send()
.await?
Expand All @@ -271,11 +286,16 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::Object;
///
/// let client = Client::default();
/// let bytes = client.object().download("my_bucket", "path/to/my/file.png").await?;
/// let bytes = client.object().download("my_bucket", "path/to/my/file.png", None).await?;
/// # Ok(())
/// # }
/// ```
pub async fn download(&self, bucket: &str, file_name: &str) -> crate::Result<Vec<u8>> {
pub async fn download(
&self,
bucket: &str,
file_name: &str,
parameters: Option<ReadParameters>,
) -> crate::Result<Vec<u8>> {
let url = format!(
"{}/b/{}/o/{}?alt=media",
crate::BASE_URL,
Expand All @@ -286,6 +306,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.get(&url)
.query(&parameters)
.headers(self.0.get_headers().await?)
.send()
.await?;
Expand All @@ -309,7 +330,7 @@ impl<'a> ObjectClient<'a> {
/// use tokio::io::{AsyncWriteExt, BufWriter};
///
/// let client = Client::default();
/// let mut stream = client.object().download_streamed("my_bucket", "path/to/my/file.png").await?;
/// let mut stream = client.object().download_streamed("my_bucket", "path/to/my/file.png", None).await?;
/// let mut file = BufWriter::new(File::create("file.png").await.unwrap());
/// while let Some(byte) = stream.next().await {
/// file.write_all(&[byte.unwrap()]).await.unwrap();
Expand All @@ -322,6 +343,7 @@ impl<'a> ObjectClient<'a> {
&self,
bucket: &str,
file_name: &str,
parameters: Option<ReadParameters>,
) -> crate::Result<impl Stream<Item = crate::Result<u8>> + Unpin> {
use futures_util::{StreamExt, TryStreamExt};
let url = format!(
Expand All @@ -334,6 +356,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.get(&url)
.query(&parameters)
.headers(self.0.get_headers().await?)
.send()
.await?
Expand All @@ -359,13 +382,17 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::Object;
///
/// let client = Client::default();
/// let mut object = client.object().read("my_bucket", "path/to/my/file.png").await?;
/// let mut object = client.object().read("my_bucket", "path/to/my/file.png", None).await?;
/// object.content_type = Some("application/xml".to_string());
/// client.object().update(&object).await?;
/// client.object().update(&object, None).await?;
/// # Ok(())
/// # }
/// ```
pub async fn update(&self, object: &Object) -> crate::Result<Object> {
pub async fn update(
&self,
object: &Object,
parameters: Option<UpdateParameters>,
) -> crate::Result<Object> {
let url = format!(
"{}/b/{}/o/{}",
crate::BASE_URL,
Expand All @@ -376,6 +403,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.put(&url)
.query(&parameters)
.headers(self.0.get_headers().await?)
.json(&object)
.send()
Expand All @@ -397,11 +425,16 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::Object;
///
/// let client = Client::default();
/// client.object().delete("my_bucket", "path/to/my/file.png").await?;
/// client.object().delete("my_bucket", "path/to/my/file.png", None).await?;
/// # Ok(())
/// # }
/// ```
pub async fn delete(&self, bucket: &str, file_name: &str) -> crate::Result<()> {
pub async fn delete(
&self,
bucket: &str,
file_name: &str,
parameters: Option<DeleteParameters>,
) -> crate::Result<()> {
let url = format!(
"{}/b/{}/o/{}",
crate::BASE_URL,
Expand All @@ -412,6 +445,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.delete(&url)
.query(&parameters)
.headers(self.0.get_headers().await?)
.send()
.await?;
Expand All @@ -431,8 +465,8 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::object::{Object, ComposeRequest, SourceObject};
///
/// let client = Client::default();
/// let obj1 = client.object().read("my_bucket", "file1").await?;
/// let obj2 = client.object().read("my_bucket", "file2").await?;
/// let obj1 = client.object().read("my_bucket", "file1", None).await?;
/// let obj2 = client.object().read("my_bucket", "file2", None).await?;
/// let compose_request = ComposeRequest {
/// kind: "storage#composeRequest".to_string(),
/// source_objects: vec![
Expand All @@ -449,7 +483,7 @@ impl<'a> ObjectClient<'a> {
/// ],
/// destination: None,
/// };
/// let obj3 = client.object().compose("my_bucket", &compose_request, "test-concatted-file").await?;
/// let obj3 = client.object().compose("my_bucket", &compose_request, "test-concatted-file", None).await?;
/// // obj3 is now a file with the content of obj1 and obj2 concatted together.
/// # Ok(())
/// # }
Expand All @@ -459,6 +493,7 @@ impl<'a> ObjectClient<'a> {
bucket: &str,
req: &ComposeRequest,
destination_object: &str,
parameters: Option<ComposeParameters>,
) -> crate::Result<Object> {
let url = format!(
"{}/b/{}/o/{}/compose",
Expand All @@ -470,6 +505,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.post(&url)
.query(&parameters)
.headers(self.0.get_headers().await?)
.json(req)
.send()
Expand All @@ -491,8 +527,8 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::object::{Object, ComposeRequest};
///
/// let client = Client::default();
/// let obj1 = client.object().read("my_bucket", "file1").await?;
/// let obj2 = client.object().copy(&obj1, "my_other_bucket", "file2").await?;
/// let obj1 = client.object().read("my_bucket", "file1", None).await?;
/// let obj2 = client.object().copy(&obj1, "my_other_bucket", "file2", None).await?;
/// // obj2 is now a copy of obj1.
/// # Ok(())
/// # }
Expand All @@ -502,6 +538,7 @@ impl<'a> ObjectClient<'a> {
object: &Object,
destination_bucket: &str,
path: &str,
parameters: Option<CopyParameters>,
) -> crate::Result<Object> {
use reqwest::header::CONTENT_LENGTH;

Expand All @@ -519,6 +556,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.post(&url)
.query(&parameters)
.headers(headers)
.send()
.await?
Expand Down Expand Up @@ -546,8 +584,8 @@ impl<'a> ObjectClient<'a> {
/// use cloud_storage::object::Object;
///
/// let client = Client::default();
/// let obj1 = client.object().read("my_bucket", "file1").await?;
/// let obj2 = client.object().rewrite(&obj1, "my_other_bucket", "file2").await?;
/// let obj1 = client.object().read("my_bucket", "file1", None).await?;
/// let obj2 = client.object().rewrite(&obj1, "my_other_bucket", "file2", None).await?;
/// // obj2 is now a copy of obj1.
/// # Ok(())
/// # }
Expand All @@ -557,6 +595,7 @@ impl<'a> ObjectClient<'a> {
object: &Object,
destination_bucket: &str,
path: &str,
parameters: Option<RewriteParameters>,
) -> crate::Result<Object> {
use reqwest::header::CONTENT_LENGTH;

Expand All @@ -574,6 +613,7 @@ impl<'a> ObjectClient<'a> {
.0
.client
.post(&url)
.query(&parameters)
.headers(headers)
.send()
.await?
Expand Down
Loading