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.
     ///

Reply via email to