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