252252//! 
253253//! # Put Object 
254254//! 
255- //! Use the [`ObjectStore ::put`] method to atomically write data. 
255+ //! Use the [`ObjectStoreExt ::put`] method to atomically write data. 
256256//! 
257257//! ``` 
258258//! # use object_store::local::LocalFileSystem; 
259- //! # use object_store::{ObjectStore, PutPayload}; 
259+ //! # use object_store::{ObjectStore, ObjectStoreExt,  PutPayload}; 
260260//! # use std::sync::Arc; 
261261//! # use object_store::path::Path; 
262262//! # fn get_object_store() -> Arc<dyn ObjectStore> { 
338338//! 
339339//! ``` 
340340//! # use object_store::local::LocalFileSystem; 
341- //! # use object_store::{ObjectStore, PutPayloadMut}; 
341+ //! # use object_store::{ObjectStore, ObjectStoreExt,  PutPayloadMut}; 
342342//! # use std::sync::Arc; 
343343//! # use bytes::Bytes; 
344344//! # use tokio::io::AsyncWriteExt; 
@@ -575,6 +575,7 @@ use bytes::Bytes;
575575use  chrono:: { DateTime ,  Utc } ; 
576576use  futures:: { stream:: BoxStream ,  StreamExt ,  TryStreamExt } ; 
577577use  std:: fmt:: { Debug ,  Formatter } ; 
578+ use  std:: future:: Future ; 
578579#[ cfg( all( feature = "fs" ,  not( target_arch = "wasm32" ) ) ) ]  
579580use  std:: io:: { Read ,  Seek ,  SeekFrom } ; 
580581use  std:: ops:: Range ; 
@@ -587,19 +588,15 @@ pub type DynObjectStore = dyn ObjectStore;
587588pub  type  MultipartId  = String ; 
588589
589590/// Universal API to multiple object store services. 
591+ /// 
592+ /// For more convience methods, check [`ObjectStoreExt`]. 
590593#[ async_trait]  
591594pub  trait  ObjectStore :  std:: fmt:: Display  + Send  + Sync  + Debug  + ' static  { 
592-     /// Save the provided bytes  to the specified location  
595+     /// Save the provided `payload`  to `location` with  the given options  
593596     /// 
594597     /// The operation is guaranteed to be atomic, it will either successfully 
595598     /// write the entirety of `payload` to `location`, or fail. No clients 
596599     /// should be able to observe a partially written object 
597-      async  fn  put ( & self ,  location :  & Path ,  payload :  PutPayload )  -> Result < PutResult >  { 
598-         self . put_opts ( location,  payload,  PutOptions :: default ( ) ) 
599-             . await 
600-     } 
601- 
602-     /// Save the provided `payload` to `location` with the given options 
603600     async  fn  put_opts ( 
604601        & self , 
605602        location :  & Path , 
@@ -609,7 +606,7 @@ pub trait ObjectStore: std::fmt::Display + Send + Sync + Debug + 'static {
609606
610607    /// Perform a multipart upload 
611608     /// 
612-      /// Client should prefer [`ObjectStore ::put`] for small payloads, as streaming uploads 
609+      /// Client should prefer [`ObjectStoreExt ::put`] for small payloads, as streaming uploads 
613610     /// typically require multiple separate requests. See [`MultipartUpload`] for more information 
614611     /// 
615612     /// For more advanced multipart uploads see [`MultipartStore`](multipart::MultipartStore) 
@@ -620,7 +617,7 @@ pub trait ObjectStore: std::fmt::Display + Send + Sync + Debug + 'static {
620617
621618    /// Perform a multipart upload with options 
622619     /// 
623-      /// Client should prefer [`ObjectStore::put `] for small payloads, as streaming uploads 
620+      /// Client should prefer [`ObjectStore::put_opts `] for small payloads, as streaming uploads 
624621     /// typically require multiple separate requests. See [`MultipartUpload`] for more information 
625622     /// 
626623     /// For more advanced multipart uploads see [`MultipartStore`](multipart::MultipartStore) 
@@ -696,7 +693,7 @@ pub trait ObjectStore: std::fmt::Display + Send + Sync + Debug + 'static {
696693     /// # async fn example() -> Result<(), Box<dyn std::error::Error>> { 
697694     /// # let root = tempfile::TempDir::new().unwrap(); 
698695     /// # let store = LocalFileSystem::new_with_prefix(root.path()).unwrap(); 
699-      /// # use object_store::{ObjectStore, ObjectMeta}; 
696+      /// # use object_store::{ObjectStore, ObjectStoreExt,  ObjectMeta}; 
700697     /// # use object_store::path::Path; 
701698     /// # use futures::{StreamExt, TryStreamExt}; 
702699     /// # 
@@ -803,10 +800,6 @@ macro_rules! as_ref_impl {
803800    ( $type: ty)  => { 
804801        #[ async_trait] 
805802        impl  ObjectStore  for  $type { 
806-             async  fn  put( & self ,  location:  & Path ,  payload:  PutPayload )  -> Result <PutResult > { 
807-                 self . as_ref( ) . put( location,  payload) . await 
808-             } 
809- 
810803            async  fn  put_opts( 
811804                & self , 
812805                location:  & Path , 
@@ -901,6 +894,30 @@ macro_rules! as_ref_impl {
901894as_ref_impl ! ( Arc <dyn ObjectStore >) ; 
902895as_ref_impl ! ( Box <dyn ObjectStore >) ; 
903896
897+ /// Extension trait for [`ObjectStore`] with convinience functions. 
898+ pub  trait  ObjectStoreExt  { 
899+     /// Save the provided bytes to the specified location 
900+      /// 
901+      /// The operation is guaranteed to be atomic, it will either successfully 
902+      /// write the entirety of `payload` to `location`, or fail. No clients 
903+      /// should be able to observe a partially written object 
904+      fn  put ( 
905+         & self , 
906+         location :  & Path , 
907+         payload :  PutPayload , 
908+     )  -> impl  Future < Output  = Result < PutResult > >  + Send ; 
909+ } 
910+ 
911+ impl < T >  ObjectStoreExt  for  T 
912+ where 
913+     T :  ObjectStore  + ?Sized , 
914+ { 
915+     async  fn  put ( & self ,  location :  & Path ,  payload :  PutPayload )  -> Result < PutResult >  { 
916+         self . put_opts ( location,  payload,  PutOptions :: default ( ) ) 
917+             . await 
918+     } 
919+ } 
920+ 
904921/// Result of a list call that includes objects, prefixes (directories) and a 
905922/// token for the next set of results. Individual result sets may be limited to 
906923/// 1,000 objects based on the underlying object storage's limitations. 
0 commit comments