From 493815e461a93c5b79df8bda5087d215ef99a352 Mon Sep 17 00:00:00 2001 From: Pratim Chaudhuri Date: Fri, 12 Jul 2024 00:27:17 +0100 Subject: [PATCH 1/6] support operation on object --- .gitignore | 3 + storage/src/http/objects/mod.rs | 2 + storage/src/http/objects/move.rs | 89 ++++++++++++++++++++++++++++++ storage/src/http/storage_client.rs | 66 ++++++++++++++-------- 4 files changed, 136 insertions(+), 24 deletions(-) create mode 100644 storage/src/http/objects/move.rs diff --git a/.gitignore b/.gitignore index 22d35163..f1116fbc 100644 --- a/.gitignore +++ b/.gitignore @@ -13,3 +13,6 @@ Cargo.lock # Added by cargo /target + +# IDE +.idea diff --git a/storage/src/http/objects/mod.rs b/storage/src/http/objects/mod.rs index 8ebf03d5..07d91ea1 100644 --- a/storage/src/http/objects/mod.rs +++ b/storage/src/http/objects/mod.rs @@ -12,6 +12,8 @@ pub mod delete; pub mod download; pub mod get; pub mod list; + +pub mod r#move; pub mod patch; pub mod rewrite; pub mod upload; diff --git a/storage/src/http/objects/move.rs b/storage/src/http/objects/move.rs new file mode 100644 index 00000000..98974b89 --- /dev/null +++ b/storage/src/http/objects/move.rs @@ -0,0 +1,89 @@ +use reqwest_middleware::{ClientWithMiddleware as Client, RequestBuilder}; + +use crate::http::objects::{Encryption, Object}; +use crate::http::{object_access_controls::Projection, Escape}; +use crate::http::objects::copy::CopyObjectRequest; +use crate::http::objects::delete::DeleteObjectRequest; + +/// Request message for GetObject. +#[derive(Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, Debug, Default)] +#[serde(rename_all = "camelCase")] +pub struct MoveObjectRequest { + /// Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. + pub destination_bucket: String, + /// Name of the new object. Required when the object metadata is not otherwise provided. Overrides the object metadata's name value, if any. + pub destination_object: String, + // Name of the source object. For information about how to URL encode object names to be path safe, see Encoding URI path parts. + pub source_object: String, + /// Name of the bucket in which to find the source object. + #[serde(skip_serializing)] + pub source_bucket: String, + + /// Makes the operation conditional on there being a live destination object with a generation number that matches the given value. Setting ifGenerationMatch to 0 makes the operation succeed only if there is no live destination object. + pub if_generation_match: Option, + /// Makes the operation conditional on there being a live destination object with a generation number that does not match the given value. If no live destination object exists, the precondition fails. Setting ifGenerationNotMatch to 0 makes the operation succeed if there is a live version of the object. + pub if_generation_not_match: Option, + /// Makes the operation conditional on there being a live destination object with a metageneration number that matches the given value. + pub if_metageneration_match: Option, + /// Makes the operation conditional on there being a live destination object with a metageneration number that does not match the given value. + pub if_metageneration_not_match: Option, + /// Makes the operation conditional on whether the source object's generation matches the given value. + pub if_source_generation_match: Option, + /// Makes the operation conditional on whether the source object's generation does not match the given value. + pub if_source_generation_not_match: Option, + /// Makes the operation conditional on whether the source object's current metageneration matches the given value. + pub if_source_metageneration_match: Option, + /// Makes the operation conditional on whether the source object's current metageneration does not match the given value. + pub if_source_metageneration_not_match: Option, + /// Set of properties to return. Defaults to noAcl, unless the object resource specifies the acl property, when it defaults to full. + /// + /// Acceptable values are: + /// full: Include all properties. + /// noAcl: Omit the owner, acl property. + pub projection: Option, + /// If present, selects a specific revision of the source object (as opposed to the latest version, the default) + pub source_generation: Option, + /// The Object metadata for updating. + #[serde(skip_serializing)] + pub metadata: Option, + + #[serde(skip_serializing)] + pub encryption: Option, +} + +impl From for CopyObjectRequest{ + fn from(value: MoveObjectRequest) -> Self { + CopyObjectRequest{ + destination_bucket: value.destination_bucket, + destination_object: value.destination_object, + source_object: value.source_object, + source_bucket: value.source_bucket, + if_generation_match: value.if_generation_match, + if_generation_not_match: value.if_generation_not_match, + if_metageneration_match: value.if_metageneration_match, + if_metageneration_not_match: value.if_metageneration_not_match, + if_source_generation_match: value.if_source_generation_match, + if_source_generation_not_match: value.if_source_generation_not_match, + if_source_metageneration_match: value.if_source_metageneration_match, + if_source_metageneration_not_match: value.if_source_metageneration_not_match, + projection: value.projection, + source_generation: value.source_generation, + metadata: value.metadata, + encryption: value.encryption, + } + } +} + +impl From for DeleteObjectRequest{ + fn from(value: MoveObjectRequest) -> Self { + DeleteObjectRequest{ + bucket: value.source_bucket, + object: value.source_object, + generation: value.source_generation, + if_generation_match: value.if_source_generation_match, + if_generation_not_match: value.if_source_generation_not_match, + if_metageneration_match: value.if_metageneration_match, + if_metageneration_not_match: value.if_metageneration_not_match, + } + } +} diff --git a/storage/src/http/storage_client.rs b/storage/src/http/storage_client.rs index 939f08f9..19792c42 100644 --- a/storage/src/http/storage_client.rs +++ b/storage/src/http/storage_client.rs @@ -1,18 +1,23 @@ use std::sync::Arc; use futures_util::{Stream, TryStream, TryStreamExt}; -use reqwest::header::{HeaderValue, CONTENT_LENGTH, LOCATION}; use reqwest::{Body, Request}; +use reqwest::header::{CONTENT_LENGTH, HeaderValue, LOCATION}; use reqwest_middleware::RequestBuilder; use google_cloud_token::TokenSource; +use crate::http::{ + bucket_access_controls, buckets, check_response_status, default_object_access_controls, Error, hmac_keys, + notifications, object_access_controls, objects, +}; +use crate::http::bucket_access_controls::BucketAccessControl; use crate::http::bucket_access_controls::delete::DeleteBucketAccessControlRequest; use crate::http::bucket_access_controls::get::GetBucketAccessControlRequest; use crate::http::bucket_access_controls::insert::InsertBucketAccessControlRequest; use crate::http::bucket_access_controls::list::{ListBucketAccessControlsRequest, ListBucketAccessControlsResponse}; use crate::http::bucket_access_controls::patch::PatchBucketAccessControlRequest; -use crate::http::bucket_access_controls::BucketAccessControl; +use crate::http::buckets::{Bucket, Policy}; use crate::http::buckets::delete::DeleteBucketRequest; use crate::http::buckets::get::GetBucketRequest; use crate::http::buckets::get_iam_policy::GetIamPolicyRequest; @@ -21,7 +26,6 @@ use crate::http::buckets::list::{ListBucketsRequest, ListBucketsResponse}; use crate::http::buckets::patch::PatchBucketRequest; use crate::http::buckets::set_iam_policy::SetIamPolicyRequest; use crate::http::buckets::test_iam_permissions::{TestIamPermissionsRequest, TestIamPermissionsResponse}; -use crate::http::buckets::{Bucket, Policy}; use crate::http::default_object_access_controls::delete::DeleteDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::get::GetDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::insert::InsertDefaultObjectAccessControlRequest; @@ -32,9 +36,9 @@ use crate::http::default_object_access_controls::patch::PatchDefaultObjectAccess use crate::http::hmac_keys::create::{CreateHmacKeyRequest, CreateHmacKeyResponse}; use crate::http::hmac_keys::delete::DeleteHmacKeyRequest; use crate::http::hmac_keys::get::GetHmacKeyRequest; +use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::hmac_keys::list::{ListHmacKeysRequest, ListHmacKeysResponse}; use crate::http::hmac_keys::update::UpdateHmacKeyRequest; -use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::notifications::delete::DeleteNotificationRequest; use crate::http::notifications::get::GetNotificationRequest; use crate::http::notifications::insert::InsertNotificationRequest; @@ -44,23 +48,20 @@ use crate::http::object_access_controls::delete::DeleteObjectAccessControlReques use crate::http::object_access_controls::get::GetObjectAccessControlRequest; use crate::http::object_access_controls::insert::InsertObjectAccessControlRequest; use crate::http::object_access_controls::list::ListObjectAccessControlsRequest; -use crate::http::object_access_controls::patch::PatchObjectAccessControlRequest; use crate::http::object_access_controls::ObjectAccessControl; +use crate::http::object_access_controls::patch::PatchObjectAccessControlRequest; use crate::http::objects::compose::ComposeObjectRequest; use crate::http::objects::copy::CopyObjectRequest; use crate::http::objects::delete::DeleteObjectRequest; use crate::http::objects::download::Range; use crate::http::objects::get::GetObjectRequest; use crate::http::objects::list::{ListObjectsRequest, ListObjectsResponse}; +use crate::http::objects::Object; use crate::http::objects::patch::PatchObjectRequest; +use crate::http::objects::r#move::MoveObjectRequest; use crate::http::objects::rewrite::{RewriteObjectRequest, RewriteObjectResponse}; use crate::http::objects::upload::{UploadObjectRequest, UploadType}; -use crate::http::objects::Object; use crate::http::resumable_upload_client::ResumableUploadClient; -use crate::http::{ - bucket_access_controls, buckets, check_response_status, default_object_access_controls, hmac_keys, notifications, - object_access_controls, objects, Error, -}; pub const SCOPES: [&str; 2] = [ "https://www.googleapis.com/auth/cloud-platform", @@ -930,6 +931,23 @@ impl StorageClient { self.send(builder).await } + #[cfg_attr(feature = "trace", tracing::instrument(skip_all))] + pub async fn move_object(&self, req: &MoveObjectRequest) -> Result { + let copy_req: CopyObjectRequest = req.clone().into(); + let delete_req: DeleteObjectRequest = req.clone().into(); + let copy_result = self.copy_object(©_req).await; + let result = if copy_result.is_ok() { + let delete_result = self.delete_object(&delete_req).await; + match delete_result { + Ok(_) => { copy_result } + Err(e) => { Err(e) } + } + } else { + copy_result + }; + result + } + /// Download the object. /// https://cloud.google.com/storage/docs/json_api/v1/objects/get /// alt is always media @@ -984,7 +1002,7 @@ impl StorageClient { &self, req: &GetObjectRequest, range: &Range, - ) -> Result>, Error> { + ) -> Result>, Error> { let builder = objects::download::build(self.v1_endpoint.as_str(), &self.http, req, range); let request = self.with_headers(builder).await?; let response = request.send().await?; @@ -1352,13 +1370,14 @@ pub(crate) mod test { use google_cloud_auth::token::DefaultTokenSourceProvider; use google_cloud_token::TokenSourceProvider; + use crate::http::bucket_access_controls::BucketACLRole; use crate::http::bucket_access_controls::delete::DeleteBucketAccessControlRequest; use crate::http::bucket_access_controls::get::GetBucketAccessControlRequest; use crate::http::bucket_access_controls::insert::{ BucketAccessControlCreationConfig, InsertBucketAccessControlRequest, }; use crate::http::bucket_access_controls::list::ListBucketAccessControlsRequest; - use crate::http::bucket_access_controls::BucketACLRole; + use crate::http::buckets::{Billing, Binding, Cors, IamConfiguration, lifecycle, Lifecycle, Website}; use crate::http::buckets::delete::DeleteBucketRequest; use crate::http::buckets::get::GetBucketRequest; use crate::http::buckets::get_iam_policy::GetIamPolicyRequest; @@ -1370,7 +1389,6 @@ pub(crate) mod test { use crate::http::buckets::patch::{BucketPatchConfig, PatchBucketRequest}; use crate::http::buckets::set_iam_policy::SetIamPolicyRequest; use crate::http::buckets::test_iam_permissions::TestIamPermissionsRequest; - use crate::http::buckets::{lifecycle, Billing, Binding, Cors, IamConfiguration, Lifecycle, Website}; use crate::http::default_object_access_controls::delete::DeleteDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::get::GetDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::insert::InsertDefaultObjectAccessControlRequest; @@ -1378,14 +1396,14 @@ pub(crate) mod test { use crate::http::hmac_keys::create::CreateHmacKeyRequest; use crate::http::hmac_keys::delete::DeleteHmacKeyRequest; use crate::http::hmac_keys::get::GetHmacKeyRequest; + use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::hmac_keys::list::ListHmacKeysRequest; use crate::http::hmac_keys::update::UpdateHmacKeyRequest; - use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::notifications::delete::DeleteNotificationRequest; + use crate::http::notifications::EventType; use crate::http::notifications::get::GetNotificationRequest; use crate::http::notifications::insert::{InsertNotificationRequest, NotificationCreationConfig}; use crate::http::notifications::list::ListNotificationsRequest; - use crate::http::notifications::EventType; use crate::http::object_access_controls::delete::DeleteObjectAccessControlRequest; use crate::http::object_access_controls::get::GetObjectAccessControlRequest; use crate::http::object_access_controls::insert::{ @@ -1393,6 +1411,7 @@ pub(crate) mod test { }; use crate::http::object_access_controls::list::ListObjectAccessControlsRequest; use crate::http::object_access_controls::ObjectACLRole; + use crate::http::objects::{Object, SourceObjects}; use crate::http::objects::compose::{ComposeObjectRequest, ComposingTargets}; use crate::http::objects::copy::CopyObjectRequest; use crate::http::objects::delete::DeleteObjectRequest; @@ -1401,9 +1420,8 @@ pub(crate) mod test { use crate::http::objects::list::ListObjectsRequest; use crate::http::objects::rewrite::RewriteObjectRequest; use crate::http::objects::upload::{Media, UploadObjectRequest, UploadType}; - use crate::http::objects::{Object, SourceObjects}; - use crate::http::resumable_upload_client::{ChunkSize, UploadStatus, UploadedRange}; - use crate::http::storage_client::{StorageClient, SCOPES}; + use crate::http::resumable_upload_client::{ChunkSize, UploadedRange, UploadStatus}; + use crate::http::storage_client::{SCOPES, StorageClient}; #[ctor::ctor] fn init() { @@ -1422,8 +1440,8 @@ pub(crate) mod test { scopes: Some(&SCOPES), sub: None, }) - .await - .unwrap(); + .await + .unwrap(); let cred = tsp.source_credentials.clone(); let ts = tsp.token_source(); let client = StorageClient::new( @@ -2195,7 +2213,7 @@ pub(crate) mod test { status1, UploadStatus::ResumeIncomplete(UploadedRange { first_byte: 0, - last_byte: chunk1_data.len() as u64 - 1 + last_byte: chunk1_data.len() as u64 - 1, }) ); @@ -2205,7 +2223,7 @@ pub(crate) mod test { status_check, UploadStatus::ResumeIncomplete(UploadedRange { first_byte: 0, - last_byte: chunk1_data.len() as u64 - 1 + last_byte: chunk1_data.len() as u64 - 1, }) ); @@ -2311,7 +2329,7 @@ pub(crate) mod test { status1, UploadStatus::ResumeIncomplete(UploadedRange { first_byte: 0, - last_byte: chunk1_data.len() as u64 - 1 + last_byte: chunk1_data.len() as u64 - 1, }) ); @@ -2325,7 +2343,7 @@ pub(crate) mod test { status1, UploadStatus::ResumeIncomplete(UploadedRange { first_byte: 0, - last_byte: chunk1_data.len() as u64 - 1 + last_byte: chunk1_data.len() as u64 - 1, }) ); From 97b4d41b888d5ee2a85eff349c6ce1cb23901df8 Mon Sep 17 00:00:00 2001 From: Pratim Chaudhuri Date: Tue, 16 Jul 2024 23:38:30 +0100 Subject: [PATCH 2/6] rust fmt --- storage/src/http/objects/move.rs | 12 ++++---- storage/src/http/storage_client.rs | 44 +++++++++++++++--------------- 2 files changed, 28 insertions(+), 28 deletions(-) diff --git a/storage/src/http/objects/move.rs b/storage/src/http/objects/move.rs index 98974b89..d96a5d55 100644 --- a/storage/src/http/objects/move.rs +++ b/storage/src/http/objects/move.rs @@ -1,9 +1,9 @@ use reqwest_middleware::{ClientWithMiddleware as Client, RequestBuilder}; -use crate::http::objects::{Encryption, Object}; -use crate::http::{object_access_controls::Projection, Escape}; use crate::http::objects::copy::CopyObjectRequest; use crate::http::objects::delete::DeleteObjectRequest; +use crate::http::objects::{Encryption, Object}; +use crate::http::{object_access_controls::Projection, Escape}; /// Request message for GetObject. #[derive(Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, Debug, Default)] @@ -51,9 +51,9 @@ pub struct MoveObjectRequest { pub encryption: Option, } -impl From for CopyObjectRequest{ +impl From for CopyObjectRequest { fn from(value: MoveObjectRequest) -> Self { - CopyObjectRequest{ + CopyObjectRequest { destination_bucket: value.destination_bucket, destination_object: value.destination_object, source_object: value.source_object, @@ -74,9 +74,9 @@ impl From for CopyObjectRequest{ } } -impl From for DeleteObjectRequest{ +impl From for DeleteObjectRequest { fn from(value: MoveObjectRequest) -> Self { - DeleteObjectRequest{ + DeleteObjectRequest { bucket: value.source_bucket, object: value.source_object, generation: value.source_generation, diff --git a/storage/src/http/storage_client.rs b/storage/src/http/storage_client.rs index 19792c42..4ecc6727 100644 --- a/storage/src/http/storage_client.rs +++ b/storage/src/http/storage_client.rs @@ -1,23 +1,18 @@ use std::sync::Arc; use futures_util::{Stream, TryStream, TryStreamExt}; +use reqwest::header::{HeaderValue, CONTENT_LENGTH, LOCATION}; use reqwest::{Body, Request}; -use reqwest::header::{CONTENT_LENGTH, HeaderValue, LOCATION}; use reqwest_middleware::RequestBuilder; use google_cloud_token::TokenSource; -use crate::http::{ - bucket_access_controls, buckets, check_response_status, default_object_access_controls, Error, hmac_keys, - notifications, object_access_controls, objects, -}; -use crate::http::bucket_access_controls::BucketAccessControl; use crate::http::bucket_access_controls::delete::DeleteBucketAccessControlRequest; use crate::http::bucket_access_controls::get::GetBucketAccessControlRequest; use crate::http::bucket_access_controls::insert::InsertBucketAccessControlRequest; use crate::http::bucket_access_controls::list::{ListBucketAccessControlsRequest, ListBucketAccessControlsResponse}; use crate::http::bucket_access_controls::patch::PatchBucketAccessControlRequest; -use crate::http::buckets::{Bucket, Policy}; +use crate::http::bucket_access_controls::BucketAccessControl; use crate::http::buckets::delete::DeleteBucketRequest; use crate::http::buckets::get::GetBucketRequest; use crate::http::buckets::get_iam_policy::GetIamPolicyRequest; @@ -26,6 +21,7 @@ use crate::http::buckets::list::{ListBucketsRequest, ListBucketsResponse}; use crate::http::buckets::patch::PatchBucketRequest; use crate::http::buckets::set_iam_policy::SetIamPolicyRequest; use crate::http::buckets::test_iam_permissions::{TestIamPermissionsRequest, TestIamPermissionsResponse}; +use crate::http::buckets::{Bucket, Policy}; use crate::http::default_object_access_controls::delete::DeleteDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::get::GetDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::insert::InsertDefaultObjectAccessControlRequest; @@ -36,9 +32,9 @@ use crate::http::default_object_access_controls::patch::PatchDefaultObjectAccess use crate::http::hmac_keys::create::{CreateHmacKeyRequest, CreateHmacKeyResponse}; use crate::http::hmac_keys::delete::DeleteHmacKeyRequest; use crate::http::hmac_keys::get::GetHmacKeyRequest; -use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::hmac_keys::list::{ListHmacKeysRequest, ListHmacKeysResponse}; use crate::http::hmac_keys::update::UpdateHmacKeyRequest; +use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::notifications::delete::DeleteNotificationRequest; use crate::http::notifications::get::GetNotificationRequest; use crate::http::notifications::insert::InsertNotificationRequest; @@ -48,20 +44,24 @@ use crate::http::object_access_controls::delete::DeleteObjectAccessControlReques use crate::http::object_access_controls::get::GetObjectAccessControlRequest; use crate::http::object_access_controls::insert::InsertObjectAccessControlRequest; use crate::http::object_access_controls::list::ListObjectAccessControlsRequest; -use crate::http::object_access_controls::ObjectAccessControl; use crate::http::object_access_controls::patch::PatchObjectAccessControlRequest; +use crate::http::object_access_controls::ObjectAccessControl; use crate::http::objects::compose::ComposeObjectRequest; use crate::http::objects::copy::CopyObjectRequest; use crate::http::objects::delete::DeleteObjectRequest; use crate::http::objects::download::Range; use crate::http::objects::get::GetObjectRequest; use crate::http::objects::list::{ListObjectsRequest, ListObjectsResponse}; -use crate::http::objects::Object; use crate::http::objects::patch::PatchObjectRequest; use crate::http::objects::r#move::MoveObjectRequest; use crate::http::objects::rewrite::{RewriteObjectRequest, RewriteObjectResponse}; use crate::http::objects::upload::{UploadObjectRequest, UploadType}; +use crate::http::objects::Object; use crate::http::resumable_upload_client::ResumableUploadClient; +use crate::http::{ + bucket_access_controls, buckets, check_response_status, default_object_access_controls, hmac_keys, notifications, + object_access_controls, objects, Error, +}; pub const SCOPES: [&str; 2] = [ "https://www.googleapis.com/auth/cloud-platform", @@ -939,8 +939,8 @@ impl StorageClient { let result = if copy_result.is_ok() { let delete_result = self.delete_object(&delete_req).await; match delete_result { - Ok(_) => { copy_result } - Err(e) => { Err(e) } + Ok(_) => copy_result, + Err(e) => Err(e), } } else { copy_result @@ -1002,7 +1002,7 @@ impl StorageClient { &self, req: &GetObjectRequest, range: &Range, - ) -> Result>, Error> { + ) -> Result>, Error> { let builder = objects::download::build(self.v1_endpoint.as_str(), &self.http, req, range); let request = self.with_headers(builder).await?; let response = request.send().await?; @@ -1370,14 +1370,13 @@ pub(crate) mod test { use google_cloud_auth::token::DefaultTokenSourceProvider; use google_cloud_token::TokenSourceProvider; - use crate::http::bucket_access_controls::BucketACLRole; use crate::http::bucket_access_controls::delete::DeleteBucketAccessControlRequest; use crate::http::bucket_access_controls::get::GetBucketAccessControlRequest; use crate::http::bucket_access_controls::insert::{ BucketAccessControlCreationConfig, InsertBucketAccessControlRequest, }; use crate::http::bucket_access_controls::list::ListBucketAccessControlsRequest; - use crate::http::buckets::{Billing, Binding, Cors, IamConfiguration, lifecycle, Lifecycle, Website}; + use crate::http::bucket_access_controls::BucketACLRole; use crate::http::buckets::delete::DeleteBucketRequest; use crate::http::buckets::get::GetBucketRequest; use crate::http::buckets::get_iam_policy::GetIamPolicyRequest; @@ -1389,6 +1388,7 @@ pub(crate) mod test { use crate::http::buckets::patch::{BucketPatchConfig, PatchBucketRequest}; use crate::http::buckets::set_iam_policy::SetIamPolicyRequest; use crate::http::buckets::test_iam_permissions::TestIamPermissionsRequest; + use crate::http::buckets::{lifecycle, Billing, Binding, Cors, IamConfiguration, Lifecycle, Website}; use crate::http::default_object_access_controls::delete::DeleteDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::get::GetDefaultObjectAccessControlRequest; use crate::http::default_object_access_controls::insert::InsertDefaultObjectAccessControlRequest; @@ -1396,14 +1396,14 @@ pub(crate) mod test { use crate::http::hmac_keys::create::CreateHmacKeyRequest; use crate::http::hmac_keys::delete::DeleteHmacKeyRequest; use crate::http::hmac_keys::get::GetHmacKeyRequest; - use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::hmac_keys::list::ListHmacKeysRequest; use crate::http::hmac_keys::update::UpdateHmacKeyRequest; + use crate::http::hmac_keys::HmacKeyMetadata; use crate::http::notifications::delete::DeleteNotificationRequest; - use crate::http::notifications::EventType; use crate::http::notifications::get::GetNotificationRequest; use crate::http::notifications::insert::{InsertNotificationRequest, NotificationCreationConfig}; use crate::http::notifications::list::ListNotificationsRequest; + use crate::http::notifications::EventType; use crate::http::object_access_controls::delete::DeleteObjectAccessControlRequest; use crate::http::object_access_controls::get::GetObjectAccessControlRequest; use crate::http::object_access_controls::insert::{ @@ -1411,7 +1411,6 @@ pub(crate) mod test { }; use crate::http::object_access_controls::list::ListObjectAccessControlsRequest; use crate::http::object_access_controls::ObjectACLRole; - use crate::http::objects::{Object, SourceObjects}; use crate::http::objects::compose::{ComposeObjectRequest, ComposingTargets}; use crate::http::objects::copy::CopyObjectRequest; use crate::http::objects::delete::DeleteObjectRequest; @@ -1420,8 +1419,9 @@ pub(crate) mod test { use crate::http::objects::list::ListObjectsRequest; use crate::http::objects::rewrite::RewriteObjectRequest; use crate::http::objects::upload::{Media, UploadObjectRequest, UploadType}; - use crate::http::resumable_upload_client::{ChunkSize, UploadedRange, UploadStatus}; - use crate::http::storage_client::{SCOPES, StorageClient}; + use crate::http::objects::{Object, SourceObjects}; + use crate::http::resumable_upload_client::{ChunkSize, UploadStatus, UploadedRange}; + use crate::http::storage_client::{StorageClient, SCOPES}; #[ctor::ctor] fn init() { @@ -1440,8 +1440,8 @@ pub(crate) mod test { scopes: Some(&SCOPES), sub: None, }) - .await - .unwrap(); + .await + .unwrap(); let cred = tsp.source_credentials.clone(); let ts = tsp.token_source(); let client = StorageClient::new( From 27a281e221d57c2971d487ba0f59b0e16eda0152 Mon Sep 17 00:00:00 2001 From: Pratim Chaudhuri Date: Wed, 17 Jul 2024 00:07:36 +0100 Subject: [PATCH 3/6] add comments --- storage/src/http/storage_client.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/storage/src/http/storage_client.rs b/storage/src/http/storage_client.rs index 4ecc6727..b58e8f61 100644 --- a/storage/src/http/storage_client.rs +++ b/storage/src/http/storage_client.rs @@ -931,6 +931,25 @@ impl StorageClient { self.send(builder).await } + /// Move the object. + /// https://cloud.google.com/storage/docs/copying-renaming-moving-objects#rest-move-object + /// This function will first make a copy of the object, and then delete the original object. + /// + /// ``` + /// use google_cloud_storage::client::Client; + /// use google_cloud_storage::http::objects::r#move::MoveObjectRequest; + /// + /// async fn run(client:Client) { + /// let result = client.move_object(&MoveObjectRequest{ + /// source_bucket: "source_bucket".to_string(), + /// source_object: "source_object".to_string(), + /// destination_bucket: "destination_source".to_string(), + /// destination_object: "destination_object".to_string(), + /// ..Default::default() + /// }).await; + /// } + /// ``` + /// #[cfg_attr(feature = "trace", tracing::instrument(skip_all))] pub async fn move_object(&self, req: &MoveObjectRequest) -> Result { let copy_req: CopyObjectRequest = req.clone().into(); From c6a91465f17a75b9528251a3f823a8b2cffa94c2 Mon Sep 17 00:00:00 2001 From: Pratim Chaudhuri Date: Wed, 17 Jul 2024 00:13:10 +0100 Subject: [PATCH 4/6] increment version --- storage/Cargo.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/Cargo.toml b/storage/Cargo.toml index 163fa68a..a90c7daa 100644 --- a/storage/Cargo.toml +++ b/storage/Cargo.toml @@ -8,7 +8,7 @@ license = "MIT" name = "google-cloud-storage" readme = "README.md" repository = "https://github.com/yoshidan/google-cloud-rust/tree/main/storage" -version = "0.20.0" +version = "0.21.0" [dependencies] anyhow = "1.0" From 9f2e42a44d6951b25aaa5822be46476feec9e9cf Mon Sep 17 00:00:00 2001 From: Pratim Chaudhuri Date: Wed, 17 Jul 2024 00:20:54 +0100 Subject: [PATCH 5/6] fix typo --- storage/src/http/objects/move.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/src/http/objects/move.rs b/storage/src/http/objects/move.rs index d96a5d55..0cd88696 100644 --- a/storage/src/http/objects/move.rs +++ b/storage/src/http/objects/move.rs @@ -5,7 +5,7 @@ use crate::http::objects::delete::DeleteObjectRequest; use crate::http::objects::{Encryption, Object}; use crate::http::{object_access_controls::Projection, Escape}; -/// Request message for GetObject. +/// Request message for moving an object. #[derive(Clone, PartialEq, Eq, serde::Deserialize, serde::Serialize, Debug, Default)] #[serde(rename_all = "camelCase")] pub struct MoveObjectRequest { From 0940c2c63130b0f9cbabc38c6ac23e4ba564b77f Mon Sep 17 00:00:00 2001 From: Pratim Chaudhuri Date: Fri, 19 Jul 2024 23:02:00 +0100 Subject: [PATCH 6/6] optimize code and return early --- storage/src/http/storage_client.rs | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/storage/src/http/storage_client.rs b/storage/src/http/storage_client.rs index b58e8f61..13b288e1 100644 --- a/storage/src/http/storage_client.rs +++ b/storage/src/http/storage_client.rs @@ -954,17 +954,10 @@ impl StorageClient { pub async fn move_object(&self, req: &MoveObjectRequest) -> Result { let copy_req: CopyObjectRequest = req.clone().into(); let delete_req: DeleteObjectRequest = req.clone().into(); - let copy_result = self.copy_object(©_req).await; - let result = if copy_result.is_ok() { - let delete_result = self.delete_object(&delete_req).await; - match delete_result { - Ok(_) => copy_result, - Err(e) => Err(e), - } - } else { - copy_result - }; - result + // Only result of the copy operations is of interest, as it contains details of destination. + let copy_result = self.copy_object(©_req).await?; + let _ = self.delete_object(&delete_req).await?; + Ok(copy_result) } /// Download the object.