Skip to content

Commit

Permalink
chore: Add output types in OperatorFutures
Browse files Browse the repository at this point in the history
Signed-off-by: Xuanwo <[email protected]>
  • Loading branch information
Xuanwo committed Apr 12, 2024
1 parent 62fe9b0 commit b6670b4
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 32 deletions.
2 changes: 1 addition & 1 deletion core/src/types/operator/operator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
114 changes: 83 additions & 31 deletions core/src/types/operator/operator_futures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,27 +38,27 @@ 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
/// users to use this struct directly.
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,
Expand All @@ -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 {
Expand All @@ -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))
Expand All @@ -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))
Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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))
Expand All @@ -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()))
Expand Down Expand Up @@ -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))
Expand All @@ -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.
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -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))
Expand All @@ -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.
///
Expand Down

0 comments on commit b6670b4

Please sign in to comment.