@@ -26,6 +26,9 @@ use crate::replication::{
2626 ReplicationResyncStatus ,
2727} ;
2828use crate :: select:: SelectOptions ;
29+ use crate :: transfer_options:: {
30+ ObjectTransferMetadata , ObjectWriteOptions , TransferCopyOptions , TransferReadOptions ,
31+ } ;
2932
3033/// Requested behavior for bucket creation.
3134#[ derive( Debug , Clone , Default , PartialEq , Eq , Serialize , Deserialize ) ]
@@ -460,6 +463,30 @@ pub trait ObjectStore: Send + Sync {
460463 self . head_object ( path) . await
461464 }
462465
466+ /// Get metadata with checksum-mode and SSE-C support when implemented by the backend.
467+ ///
468+ /// The default preserves legacy version selection and rejects advanced options explicitly.
469+ async fn head_object_with_transfer_options (
470+ & self ,
471+ path : & RemotePath ,
472+ options : & TransferReadOptions ,
473+ ) -> Result < ObjectInfo > {
474+ let legacy = options. legacy_read_options ( ) ?;
475+ self . head_object_with_options ( path, & legacy) . await
476+ }
477+
478+ /// Read complete transfer metadata without changing ObjectInfo's stable output contract.
479+ async fn head_object_transfer_metadata (
480+ & self ,
481+ _path : & RemotePath ,
482+ options : & TransferReadOptions ,
483+ ) -> Result < ObjectTransferMetadata > {
484+ options. validate ( ) ?;
485+ Err ( Error :: UnsupportedFeature (
486+ "Complete transfer metadata is not implemented by this object store" . to_string ( ) ,
487+ ) )
488+ }
489+
463490 /// Check if a bucket exists
464491 async fn bucket_exists ( & self , bucket : & str ) -> Result < bool > ;
465492
@@ -516,6 +543,18 @@ pub trait ObjectStore: Send + Sync {
516543 self . get_object ( path) . await
517544 }
518545
546+ /// Read an object with checksum-mode and SSE-C support when implemented by the backend.
547+ ///
548+ /// The default preserves legacy version selection and rejects advanced options explicitly.
549+ async fn get_object_with_transfer_options (
550+ & self ,
551+ path : & RemotePath ,
552+ options : & TransferReadOptions ,
553+ ) -> Result < Vec < u8 > > {
554+ let legacy = options. legacy_read_options ( ) ?;
555+ self . get_object_with_options ( path, & legacy) . await
556+ }
557+
519558 /// Stream current object content or an exact historical version to a writer.
520559 async fn write_object_to_with_options (
521560 & self ,
@@ -534,6 +573,21 @@ pub trait ObjectStore: Send + Sync {
534573 Ok ( write_len as u64 )
535574 }
536575
576+ /// Stream an object with checksum-mode and SSE-C support when implemented by the backend.
577+ ///
578+ /// The default preserves legacy version selection and rejects advanced options explicitly.
579+ async fn write_object_to_with_transfer_options (
580+ & self ,
581+ path : & RemotePath ,
582+ options : & TransferReadOptions ,
583+ writer : & mut ( dyn AsyncWrite + Send + Unpin ) ,
584+ max_bytes : Option < u64 > ,
585+ ) -> Result < u64 > {
586+ let legacy = options. legacy_read_options ( ) ?;
587+ self . write_object_to_with_options ( path, & legacy, writer, max_bytes)
588+ . await
589+ }
590+
537591 /// Upload object from bytes
538592 async fn put_object (
539593 & self ,
@@ -543,6 +597,20 @@ pub trait ObjectStore: Send + Sync {
543597 encryption : Option < & ObjectEncryptionRequest > ,
544598 ) -> Result < ObjectInfo > ;
545599
600+ /// Upload an object with complete transfer-fidelity options.
601+ ///
602+ /// The default delegates Content-Type and managed encryption to the legacy API and rejects
603+ /// every option that cannot be represented there.
604+ async fn put_object_with_options (
605+ & self ,
606+ path : & RemotePath ,
607+ data : Vec < u8 > ,
608+ options : & ObjectWriteOptions ,
609+ ) -> Result < ObjectInfo > {
610+ let ( content_type, encryption) = options. legacy_put_arguments ( ) ?;
611+ self . put_object ( path, data, content_type, encryption) . await
612+ }
613+
546614 /// Delete an object
547615 async fn delete_object ( & self , path : & RemotePath ) -> Result < ( ) > ;
548616
@@ -606,6 +674,21 @@ pub trait ObjectStore: Send + Sync {
606674 self . copy_object ( src, dst, encryption) . await
607675 }
608676
677+ /// Copy an object with explicit metadata, tags, checksum, SSE-C, and lock intent.
678+ ///
679+ /// The default preserves legacy source-version and managed-encryption behavior while
680+ /// rejecting every advanced option that the original API cannot represent.
681+ async fn copy_object_with_transfer_options (
682+ & self ,
683+ src : & RemotePath ,
684+ dst : & RemotePath ,
685+ options : & TransferCopyOptions ,
686+ ) -> Result < ObjectInfo > {
687+ let ( legacy, encryption) = options. legacy_copy_arguments ( ) ?;
688+ self . copy_object_with_options ( src, dst, & legacy, encryption)
689+ . await
690+ }
691+
609692 /// Copy an object with S3's multipart server-side copy lifecycle.
610693 ///
611694 /// Backends that do not implement multipart copy fail explicitly. The
@@ -624,6 +707,25 @@ pub trait ObjectStore: Send + Sync {
624707 ) )
625708 }
626709
710+ /// Copy an object through the multipart lifecycle with transfer-fidelity options.
711+ ///
712+ /// The default delegates only when all requested fidelity can be represented by the legacy
713+ /// multipart API. Implementations must override this method before accepting advanced fields.
714+ async fn multipart_copy_with_transfer_options (
715+ & self ,
716+ src : & RemotePath ,
717+ dst : & RemotePath ,
718+ multipart : & MultipartCopyOptions ,
719+ transfer : & TransferCopyOptions ,
720+ cancellation : & MultipartCopyCancellation ,
721+ on_progress : & MultipartCopyProgress < ' _ > ,
722+ ) -> Result < MultipartCopyResult > {
723+ transfer. validate_multipart_source_version ( multipart. source_version_id . as_deref ( ) ) ?;
724+ let ( _, encryption) = transfer. legacy_copy_arguments ( ) ?;
725+ self . multipart_copy ( src, dst, multipart, cancellation, encryption, on_progress)
726+ . await
727+ }
728+
627729 /// Generate a presigned URL for an object
628730 async fn presign_get ( & self , path : & RemotePath , expires_secs : u64 ) -> Result < String > ;
629731
0 commit comments