This is an automated email from the ASF dual-hosted git repository. xuanwo pushed a commit to branch refactor-operator-fut in repository https://gitbox.apache.org/repos/asf/opendal.git
commit b6670b405cc4ccfab971d4b16ba8641b09630a61 Author: Xuanwo <[email protected]> AuthorDate: Fri Apr 12 22:26:42 2024 +0800 chore: Add output types in OperatorFutures Signed-off-by: Xuanwo <[email protected]> --- core/src/types/operator/operator.rs | 2 +- core/src/types/operator/operator_futures.rs | 114 ++++++++++++++++++++-------- 2 files changed, 84 insertions(+), 32 deletions(-) diff --git a/core/src/types/operator/operator.rs b/core/src/types/operator/operator.rs index 4e6bea5e64..d004b5ec17 100644 --- a/core/src/types/operator/operator.rs +++ b/core/src/types/operator/operator.rs @@ -1788,7 +1788,7 @@ impl Operator { /// # Ok(()) /// # } /// ``` - pub fn lister_with(&self, path: &str) -> FutureList<impl Future<Output = Result<Lister>>> { + pub fn lister_with(&self, path: &str) -> FutureLister<impl Future<Output = Result<Lister>>> { let path = normalize_path(path); OperatorFuture::new( diff --git a/core/src/types/operator/operator_futures.rs b/core/src/types/operator/operator_futures.rs index c4ddd86e74..cb4b4cbc1d 100644 --- a/core/src/types/operator/operator_futures.rs +++ b/core/src/types/operator/operator_futures.rs @@ -38,18 +38,18 @@ use crate::*; /// /// This struct is by design to keep in crate. We don't want /// users to use this struct directly. -pub struct OperatorFuture<T, F> { +pub struct OperatorFuture<I, O, F: Future<Output = Result<O>>> { /// The accessor to the underlying object storage acc: FusedAccessor, /// The path of string path: String, /// The input args - args: T, + args: I, /// The function which will move all the args and return a static future - f: fn(FusedAccessor, String, T) -> F, + f: fn(FusedAccessor, String, I) -> F, } -impl<T, F: Future> OperatorFuture<T, F> { +impl<I, O, F: Future<Output = Result<O>>> OperatorFuture<I, O, F> { /// # NOTES /// /// This struct is by design to keep in crate. We don't want @@ -57,8 +57,8 @@ impl<T, F: Future> OperatorFuture<T, F> { pub(crate) fn new( inner: FusedAccessor, path: String, - args: T, - f: fn(FusedAccessor, String, T) -> F, + args: I, + f: fn(FusedAccessor, String, I) -> F, ) -> Self { OperatorFuture { acc: inner, @@ -69,19 +69,19 @@ impl<T, F: Future> OperatorFuture<T, F> { } } -impl<T, F> OperatorFuture<T, F> { +impl<I, O, F: Future<Output = Result<O>>> OperatorFuture<I, O, F> { /// Change the operation's args. - fn map(mut self, f: impl FnOnce(T) -> T) -> Self { + fn map(mut self, f: impl FnOnce(I) -> I) -> Self { self.args = (f)(self.args); self } } -impl<T, F> IntoFuture for OperatorFuture<T, F> +impl<I, O, F> IntoFuture for OperatorFuture<I, O, F> where - F: Future, + F: Future<Output = Result<O>>, { - type Output = F::Output; + type Output = Result<O>; type IntoFuture = F; fn into_future(self) -> Self::IntoFuture { @@ -92,9 +92,9 @@ where /// Future that generated by [`Operator::stat_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FutureStat<F> = OperatorFuture<OpStat, F>; +pub type FutureStat<F> = OperatorFuture<OpStat, Metadata, F>; -impl<F> FutureStat<F> { +impl<F: Future<Output = Result<Metadata>>> FutureStat<F> { /// Set the If-Match for this operation. pub fn if_match(self, v: &str) -> Self { self.map(|args| args.with_if_match(v)) @@ -114,9 +114,9 @@ impl<F> FutureStat<F> { /// Future that generated by [`Operator::presign_stat_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FuturePresignStat<F> = OperatorFuture<(OpStat, Duration), F>; +pub type FuturePresignStat<F> = OperatorFuture<(OpStat, Duration), PresignedRequest, F>; -impl<F> FuturePresignStat<F> { +impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignStat<F> { /// Sets the content-disposition header that should be send back by the remote read operation. pub fn override_content_disposition(self, v: &str) -> Self { self.map(|(args, dur)| (args.with_override_content_disposition(v), dur)) @@ -146,9 +146,9 @@ impl<F> FuturePresignStat<F> { /// Future that generated by [`Operator::presign_read_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FuturePresignRead<F> = OperatorFuture<(OpRead, Duration), F>; +pub type FuturePresignRead<F> = OperatorFuture<(OpRead, Duration), PresignedRequest, F>; -impl<F> FuturePresignRead<F> { +impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignRead<F> { /// Sets the content-disposition header that should be send back by the remote read operation. pub fn override_content_disposition(self, v: &str) -> Self { self.map(|(args, dur)| (args.with_override_content_disposition(v), dur)) @@ -178,9 +178,9 @@ impl<F> FuturePresignRead<F> { /// Future that generated by [`Operator::presign_write_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FuturePresignWrite<F> = OperatorFuture<(OpWrite, Duration), F>; +pub type FuturePresignWrite<F> = OperatorFuture<(OpWrite, Duration), PresignedRequest, F>; -impl<F> FuturePresignWrite<F> { +impl<F: Future<Output = Result<PresignedRequest>>> FuturePresignWrite<F> { /// Set the content type of option pub fn content_type(self, v: &str) -> Self { self.map(|(args, dur)| (args.with_content_type(v), dur)) @@ -200,9 +200,9 @@ impl<F> FuturePresignWrite<F> { /// Future that generated by [`Operator::read_with`] or [`Operator::reader_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FutureRead<F> = OperatorFuture<(OpRead, BytesRange), F>; +pub type FutureRead<F> = OperatorFuture<(OpRead, BytesRange), Buffer, F>; -impl<F> FutureRead<F> { +impl<F: Future<Output = Result<Buffer>>> FutureRead<F> { /// Set the range header for this operation. pub fn range(self, range: impl RangeBounds<u64>) -> Self { self.map(|(args, _)| (args, range.into())) @@ -231,9 +231,9 @@ impl<F> FutureRead<F> { /// # Notes /// /// `(OpRead, ())` is a trick to make sure `FutureReader` is different from `FutureRead` -pub type FutureReader<F> = OperatorFuture<OpRead, F>; +pub type FutureReader<F> = OperatorFuture<OpRead, Reader, F>; -impl<F> FutureReader<F> { +impl<F: Future<Output = Result<Reader>>> FutureReader<F> { /// Set the version for this operation. pub fn version(self, v: &str) -> Self { self.map(|args| args.with_version(v)) @@ -243,9 +243,9 @@ impl<F> FutureReader<F> { /// Future that generated by [`Operator::write_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FutureWrite<F> = OperatorFuture<(OpWrite, Bytes), F>; +pub type FutureWrite<F> = OperatorFuture<(OpWrite, Bytes), (), F>; -impl<F> FutureWrite<F> { +impl<F: Future<Output = Result<()>>> FutureWrite<F> { /// Set the append mode of op. /// /// If the append mode is set, the data will be appended to the end of the file. @@ -293,9 +293,9 @@ impl<F> FutureWrite<F> { /// Future that generated by [`Operator::writer_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FutureWriter<F> = OperatorFuture<OpWrite, F>; +pub type FutureWriter<F> = OperatorFuture<OpWrite, Writer, F>; -impl<F> FutureWriter<F> { +impl<F: Future<Output = Result<Writer>>> FutureWriter<F> { /// Set the append mode of op. /// /// If the append mode is set, the data will be appended to the end of the file. @@ -350,9 +350,9 @@ impl<F> FutureWriter<F> { /// Future that generated by [`Operator::delete_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FutureDelete<F> = OperatorFuture<OpDelete, F>; +pub type FutureDelete<F> = OperatorFuture<OpDelete, (), F>; -impl<F> FutureDelete<F> { +impl<F: Future<Output = Result<()>>> FutureDelete<F> { /// Change the version of this delete operation. pub fn version(self, v: &str) -> Self { self.map(|args| args.with_version(v)) @@ -362,9 +362,61 @@ impl<F> FutureDelete<F> { /// Future that generated by [`Operator::list_with`] or [`Operator::lister_with`]. /// /// Users can add more options by public functions provided by this struct. -pub type FutureList<F> = OperatorFuture<OpList, F>; +pub type FutureList<F> = OperatorFuture<OpList, Vec<Entry>, F>; -impl<F> FutureList<F> { +impl<F: Future<Output = Result<Vec<Entry>>>> FutureList<F> { + /// The limit passed to underlying service to specify the max results + /// that could return per-request. + /// + /// Users could use this to control the memory usage of list operation. + pub fn limit(self, v: usize) -> Self { + self.map(|args| args.with_limit(v)) + } + + /// The start_after passes to underlying service to specify the specified key + /// to start listing from. + pub fn start_after(self, v: &str) -> Self { + self.map(|args| args.with_start_after(v)) + } + + /// The recursive is used to control whether the list operation is recursive. + /// + /// - If `false`, list operation will only list the entries under the given path. + /// - If `true`, list operation will list all entries that starts with given path. + /// + /// Default to `false`. + pub fn recursive(self, v: bool) -> Self { + self.map(|args| args.with_recursive(v)) + } + + /// Metakey is used to control which meta should be returned. + /// + /// Lister will make sure the result for specified meta is **known**: + /// + /// - `Some(v)` means exist. + /// - `None` means services doesn't have this meta. + /// + /// The default metakey is `Metakey::Mode`. + pub fn metakey(self, v: impl Into<FlagSet<Metakey>>) -> Self { + self.map(|args| args.with_metakey(v)) + } + + /// Concurrent is used to control the number of concurrent stat requests. + /// + /// If concurrent is set to <=1, the lister will perform stat requests sequentially. + /// + /// The default concurrent is 1. + pub fn concurrent(self, v: usize) -> Self { + self.map(|args| args.with_concurrent(v)) + } +} + +/// Future that generated by [`Operator::list_with`] or [`Operator::lister_with`]. +/// +/// Users can add more options by public functions provided by this struct. +pub type FutureLister<F> = OperatorFuture<OpList, Lister, F>; + +impl<F: Future<Output = Result<Lister>>> FutureLister<F> { /// The limit passed to underlying service to specify the max results /// that could return per-request. ///
